Skip to content

Commit f796421

Browse files
committed
fix(sdk): fail faster when json.loads encounters non-JSON content
When the buffer contains non-JSON content (e.g., control characters like \a from shell hooks), json.loads fails and the code continues waiting indefinitely for valid JSON, causing 10+ minute timeouts. This fix detects when the buffer contains non-JSON content at the start (after stripping whitespace) and raises SDKJSONDecodeError immediately instead of waiting forever. Fixes anthropics#678
1 parent 15b5ece commit f796421

1 file changed

Lines changed: 12 additions & 2 deletions

File tree

src/claude_agent_sdk/_internal/transport/subprocess_cli.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,18 @@ async def _read_messages_impl(self) -> AsyncIterator[dict[str, Any]]:
557557
data = json.loads(json_buffer)
558558
json_buffer = ""
559559
yield data
560-
except json.JSONDecodeError:
561-
# We are speculatively decoding the buffer until we get
560+
except json.JSONDecodeError as e:
561+
# Check if buffer contains non-JSON content (e.g., control characters)
562+
# that makes it impossible to ever parse successfully
563+
stripped = json_buffer.lstrip()
564+
if stripped and not stripped.startswith(("{", "[")):
565+
# Buffer contains garbage at the start, clear it and raise
566+
json_buffer = ""
567+
raise SDKJSONDecodeError(
568+
"Buffer contains non-JSON content",
569+
e,
570+
) from e
571+
# Otherwise, we are speculatively decoding the buffer until we get
562572
# a full JSON object. If there is an actual issue, we
563573
# raise an error after exceeding the configured limit.
564574
continue

0 commit comments

Comments
 (0)