Skip to content

Surface actionable hint for Popen(timeout=) TypeError misread as API timeout (fixes #3) - #12

Merged
ericwang915 merged 1 commit into
mainfrom
cursor/fix-issue-3-popen-timeout-hint-8d2a
Sep 8, 2026
Merged

ericwang915 merged 1 commit into
mainfrom
cursor/fix-issue-3-popen-timeout-hint-8d2a

Conversation

@ericwang915

Copy link
Copy Markdown
Owner

Root cause of #3

The "timeout errors" in #3 are not network/API timeouts. The screenshot attached to the issue reads:

PythonClaw execution failed: Popen.__init__() got an unexpected keyword argument 'timeout'

That is a Python TypeError from a script the agent generated/executed at runtime via run_command: it called subprocess.Popen(cmd, timeout=N), but Popen has no timeout parameter (that argument belongs to subprocess.run() / communicate()). The only salient word in the bare error is "timeout", so the reporter understandably blamed their API binding — which was fine all along.

Investigation notes:

  • The crash does not come from PythonClaw's own code: Popen appears only in daemon.py (without timeout) across every git revision and every published PyPI wheel (0.2.0 → 0.7.2), and the literal error/output strings from the screenshot appear nowhere in the codebase.
  • LLM client timeouts are already generous (300 s across OpenAI-compatible/Anthropic/Gemini clients), so there is no real too-short-timeout bug to fix.
  • Reproduced end-to-end: running such a script through run_command returns only the bare traceback, which the model then relays to the user as a generic "timeout" failure.

Fix (DX)

run_command now detects the Popen.__init__() got an unexpected keyword argument '...' pattern in script output and appends an actionable hint to the tool result:

[hint] This TypeError comes from the executed script itself — subprocess.Popen() does not accept
a `timeout` keyword argument. It is NOT a network/API timeout and NOT an LLM key problem.
Fix the script: use `subprocess.run(cmd, timeout=N)` or `proc = subprocess.Popen(cmd);
proc.communicate(timeout=N)` instead of passing `timeout=` to Popen(), then rerun it.
  • The hint fires on the failure path and on exit-0 output (scripts that swallow the exception with a catch-all except and print it, matching the exact phrasing in the screenshot).
  • Since the hint is part of the tool result fed back to the model, the agent can fix the script on the next round instead of surfacing a misleading failure to the user.
  • Added a README troubleshooting subsection distinguishing this failure from real network timeouts (with the baseUrl/curl $BASEURL/models guidance from the maintainer's issue comment).

Testing

  • New tests/test_tool_error_hints.py: 7 tests covering the hint matcher (traceback form, bare-exception form, non-timeout kwargs, unrelated errors) and run_command integration (crash path, swallowed-exception path, clean output).
  • Full suite: 190 passed.

Fixes #3.

Open in Web Open in Cursor 

The 'timeout errors' in #3 are not network/API timeouts: the screenshot
shows a TypeError from a runtime-generated script calling
subprocess.Popen(cmd, timeout=N), which Popen does not accept. The only
salient word in the bare error is 'timeout', so users blame their API
binding.

run_command now detects this pattern in script output (including when
the script swallows the exception and exits 0) and appends a hint that
names the real cause and the fix, letting the agent self-correct on the
next tool round instead of surfacing a misleading failure. Adds a README
troubleshooting note distinguishing this from real network timeouts.

Co-authored-by: Eric Wang <wangchen2007915@gmail.com>
@ericwang915
ericwang915 marked this pull request as ready for review September 8, 2026 08:05
@ericwang915
ericwang915 merged commit d486df1 into main Sep 8, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PythonClaw keeps giving me timeout errors even after I've bound the API.

2 participants