[Bug] ModelClient: Missing error handling for JSON parsing and blocking I/O in async methods
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- python
- Domain
- api, performance
Research direction
Locate the ModelClient implementation and inspect parse_request_line(), parse_response_line(), read_last_request_line(), read_last_response_line(), wait_for_first_request(), and _append_response(). Reproduce the malformed-meta JSON case, then verify parsing failures have useful context and the listed async file operations no longer block the event loop.
Written by the indexing model from the issue text.
Description
Bug Description
ModelClient in Python SDK has two major issues:
-
Missing error handling for
json.loads(): Theparse_request_line()andparse_response_line()methods calljson.loads(meta_json)without try/catch. If the log file is partially written or corrupted, this will throw an unhandledJSONDecodeErrorexception. -
Synchronous file I/O in async methods: All file operations (
read_last_request_line(),read_last_response_line(),wait_for_first_request(),_append_response()) use synchronousopen()andreadlines()insideasyncmethods. This blocks the asyncio event loop and defeats the purpose of using async/await.
Steps to Reproduce
- Create a
ModelClientinstance - Simulate a corrupted log file with malformed JSON in the meta section:
# Write a corrupted line to the log file with open(log_file, 'w') as f: f.write("__REQUEST_START__some_request__REQUEST_END__{invalid json}\n") - Call
await client.pop_request(1) - Observe the unhandled
JSONDecodeError
Expected Behavior
json.loads()should be wrapped in try/catch, and a meaningful error should be raised or logged when JSON parsing fails.- File I/O operations should use async libraries like
aiofilesto avoid blocking the event loop.
Actual Behavior
JSONDecodeErroris thrown without context, making it difficult to debug log file issues.- Async methods perform blocking I/O, which can cause performance issues in high-concurrency scenarios.
Error Logs
Traceback (most recent call last):
File "...", line X, in parse_request_line
meta = json.loads(meta_json)
^^^^^^^^^^^^^^^^^^^^^
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Environment Information
- OS: [e.g. Ubuntu 22.04, macOS 13.0, Windows 11]
- Python Version: [e.g. 3.11.5]
- ROCK Version: [e.g. 0.2.0]
- Installation Method: [e.g. pip install rl-rock, source installation with uv]
- Docker Version: [e.g. 24.0.6] (if using sandbox features)
- Deployment Type: [e.g. local, distributed, ray]
ROCK Configuration
- Runtime Environment Type: [e.g. uv, pip, conda]
- Sandbox Image: [e.g. python:3.11, custom image]
- Resource Allocation: [e.g. memory=8g, cpus=2.0]
Component Affected
- Sandbox
- Actions
- Deployments
- SDK & API
- Envhub
- CLI
- Performance & Optimization
- Documentation & Examples
Suggested Fix
- Add try/catch for JSON parsing:
async def parse_request_line(self, line_content: str) -> tuple[str, dict]:
if SESSION_END_MARKER in line_content:
return SESSION_END_MARKER, {}
try:
meta_json = line_content.split(REQUEST_END_MARKER)[1]
request_json = line_content.split(REQUEST_END_MARKER)[0].split(REQUEST_START_MARKER)[1]
meta = json.loads(meta_json)
return request_json, meta
except (IndexError, json.JSONDecodeError) as e:
logger.error(f"Failed to parse request line: {line_content!r}, error: {e}")
raise ValueError(f"Invalid request line format: {e}") from e
- Use
aiofilesfor async file I/O:
import aiofiles
async def read_last_request_line(self) -> str:
async with aiofiles.open(self.log_file) as f:
lines = await f.readlines()
# ... rest of the logic
Or alternatively, use asyncio.to_thread() to wrap synchronous I/O:
async def read_last_request_line(self) -> str:
def _sync_read():
with open(self.log_file) as f:
return f.readlines()
lines = await asyncio.to_thread(_sync_read)
# ... rest of the logic
- Dominant language
- Python
- Stars
- 490
- Forks
- 83
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 1
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from alibaba/ROCK
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
docs: add image mirror guide for v1.9.xPossibly taken @jake11-oho claimed this 118 days ago. Open
Difficulty 2/5 1-2 days Newbie friendliness 75/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Similar issues
-
bug good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
yunaremaia/proto-drift#22 ·
-
bug good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
yunaremaia/memwatch#96 ·
-
bug good first issue
Difficulty 1/5 Under an hour Newbie friendliness 91/100
yunaremaia/ci-gate-watch#34 ·
-
bug good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
yunaremaia/agent-capability-attestation#64 ·
Maintainers usually reply within 1 day
-
bug good first issue
Difficulty 1/5 Under an hour Newbie friendliness 86/100
yunaremaia/agent-call-graph#43 ·
Maintainers usually reply within 1 day