GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix(templates): read long stream-json lines and bound Claude Code shutdown by michaelxu2288 · Pull Request #542 · scaleapi/scale-agentex-python

Conversation

@michaelxu2288

@michaelxu2288 michaelxu2288 commented Oct 1, 2026 •
edited by greptile-apps Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Problem

The Claude Code scaffolds (sync-claude-code, default-claude-code, temporal-claude-code) and their tutorial copies (00_sync/060, 10_async/00_base/130, 10_async/10_temporal/140) share two bugs in how they read the CLI.

1. Lines over 64 KiB abort the turn. stdout is read through asyncio's StreamReader with its default 64 KiB limit (async for chunk in proc.stdout is readline() underneath). Claude Code writes one JSON line per event, so a tool_result that echoes a large file read is a single line far past 64 KiB. readline() then raises ValueError: Separator is found, but chunk is longer than limit, and the turn fails before its result event. The same class of bug was already fixed for agentex agents run (SUBPROCESS_STREAM_LIMIT in cli_utils.py).

2. Cancellation can hang. Cleanup sends SIGTERM and then awaits proc.wait() with no bound. A CLI that ignores or delays SIGTERM blocks request cancellation (sync/async ACP) or Temporal activity cancellation indefinitely.

Fix

In each of the six files:

  • read stdout with limit=STDOUT_LINE_LIMIT (8 MiB);
  • after SIGTERM, wait at most TERMINATE_TIMEOUT_SECONDS (5 s), then SIGKILL;
  • document both in _spawn_claude's docstring.

Nothing else changes. The Codex templates read with read(4096) and use kill(), so neither bug applies to them. The Gemini CLI templates in #516 got the same treatment.

Verification

I put a fake claude on PATH and drove _spawn_claude() from the rendered sync and Temporal templates.

case main this branch
100,000-character stream-json line ValueError: Separator is found, but chunk is longer than limit line read whole
CLI ignores SIGTERM, consumer calls aclose() still hanging after 20 s returns after 5.0 s
  • tests/lib/cli/test_init_templates.py: 26 passed.
  • Each tutorial's tests/test_agent_offline.py: 7, 5 and 5 passed.
  • ruff check is clean on the tutorial files, and all three compile.

RetriggerConfidence Score: 5/5

The PR appears safe to merge; the earlier missing-test concern is addressed.

What we checked:

  • Subprocess command injection: No. The subprocess receives a fixed command without a shell, and the prompt is written to stdin. The new argument only sets the stdout read limit.

Summary

Claude Code scaffolds now read stream-JSON lines up to 8 MiB and stop lingering CLI processes after a five-second grace period. The updates cover the generated templates and tutorial copies, with an offline subprocess test for both paths.

  • Large tool_result lines can reach the turn without hitting asyncio’s default line limit.
  • Early shutdown sends SIGTERM, then SIGKILL if the CLI is still running after five seconds.

Reviews (2) · Last reviewed commit: "test(templates): run the Claude Code sca..."

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

greptile-apps[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@michaelxu2288
fix(templates): read long stream-json lines and bound Claude Code shu…
a35652a
…tdown

The Claude Code scaffolds (sync, async and Temporal) and their tutorial
copies read `claude -p --output-format stream-json` stdout through
asyncio's StreamReader with the default 64 KiB line limit. Claude Code
writes one JSON line per event, so a tool_result that echoes a large
file read is a single line well past 64 KiB; readline() then raises
"Separator is found, but chunk is longer than limit" and the turn aborts.
Read with an 8 MiB limit, the same value `agentex agents run` uses for
its child processes.

Their cleanup also sent SIGTERM and then awaited proc.wait() with no
bound, so a CLI that ignores or delays SIGTERM hangs request or activity
cancellation. Wait at most 5 s, then SIGKILL.

Verified with a fake `claude` on PATH, against the rendered sync and
Temporal templates:
- a 100,000-character line: main raises the ValueError, this branch reads
  it whole;
- a CLI that ignores SIGTERM: main's aclose() is still hanging after
  20 s, this branch returns after 5 s.
tests/lib/cli/test_init_templates.py passes, and the three tutorials'
test_agent_offline.py suites pass (7, 5 and 5 tests).
greptile-apps[bot]
greptile-apps Bot reviewed Oct 1, 2026
View reviewed changes
Comment thread src/agentex/lib/cli/templates/sync-claude-code/project/acp.py.j2 Resolved

Uh oh!

There was an error while loading. Please reload this page.

@michaelxu2288
test(templates): run the Claude Code scaffold against a real child pr…
1c487a2
…ocess

Render the sync Claude Code template, put a fake `claude` on PATH that
prints a 100,000-character stream-json line and ignores SIGTERM, and
drive _spawn_claude(): the long line must arrive whole and aclose() must
return once the (shortened) grace period ends. Against main's template
the test fails with "Separator is found, but chunk is longer than limit"
after the unbounded wait sits out the child's 60 s sleep; here it passes
in under 4 s.
@michaelxu2288

michaelxu2288 commented Oct 10, 2026

Copy link
Copy Markdown
Author

@danielmillerp since you were just in the tutorials: this fixes the Claude Code templates and their three tutorial copies crashing on any stream-json line over 64 KiB (a large file read does it), plus an unbounded wait on cancel. Would you mind taking a look? CI needs a maintainer to approve the run since this is from a fork.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@stephen-wang24 stephen-wang24 mentioned this pull request Oct 26, 2026
fix(cli): sandbox the claude-code harness and run the local ACP on loopback #554
Closed

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@greptile-apps greptile-apps[bot] greptile-apps[bot] left review comments

At least 1 approving review is required to merge this pull request.

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@michaelxu2288
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.