Repository navigation
fix(proxy): bounded EADDRINUSE retry for the mitmdump listen port - #36
Merged
Merged
Conversation
The port is chosen by bind-then-close of a throwaway net server
(getFreePort) and handed to mitmdump via --listen-port moments later — a
TOCTOU gap in which any other process can grab the port. When that
happens mitmdump exits 'Address already in use' before writing its CA,
waitForCa throws, and the whole provider session (the spine of every
Claude run) fails to start with no retry (agent-code#495 A7).
start() now retries up to 3 attempts, re-running getFreePort and
rewriting info.proxyPort/proxyUrl per attempt. Retry-with-fresh-port was
chosen over --listen-port 0 because the bound port would have to be
scraped from mitmdump's human-readable stderr banner (version-fragile)
and info.proxyUrl consumers would need a post-start handshake; with the
retry, info is final once start() resolves, which is the existing
contract (claudeSession reads info.proxyUrl only after awaiting start()).
Only the pre-CA port-collision death retries (matched on the stable
'address already in use'/EADDRINUSE substrings from the stderr tail that
waitForCa embeds in its error). Everything else rethrows immediately.
Cleanup between attempts is manual (child=null, reset exit fields, clear
stderr tail) rather than stop() — stop()'s child.once('exit') handshake
never fires for an already-exited process and would hang forever.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Juliusolsson05
force-pushed
the
fix/mitmdump-port-eaddrinuse-retry
branch
from
July 21, 2026 14:27
280522e to
8c3f495
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fixes the getFreePort →
--listen-portTOCTOU (Juliusolsson05/agent-code#495 finding A7): on a busy machine another process can take the port in the gap between the throwaway bind-then-close and mitmdump's own bind; mitmdump exits address already in use before writing its CA and the whole Claude session fails to start, with no retry.start()now retries up to 3 attempts with a fresh port each time, mutatinginfo.proxyPort/info.proxyUrlper attempt.Design notes:
--listen-port 0: the actually-bound port would have to be scraped from mitmdump's human-readable stderr banner (version-fragile), andinfo.proxyUrlconsumers would need a post-start handshake. With retry,infois final oncestart()resolves — the existing contract (agent-code'sclaudeSessionreadsinfo.proxyUrlonly after awaitingstart()).address already in use/EADDRINUSEsubstrings from the stderr tailwaitForCaembeds); every other failure rethrows immediately and still writesstartup-error.json.stop()—stop()'schild.once('exit')handshake never fires for an already-exited child and would hang.Verified by type-checking through the agent-code superproject gate (
tsc -b tsconfig.node.jsonwith this file patched intopackages/claude-code-headless), since the package has no standalone@types/nodedevDep.The agent-code submodule pointer bump follows in Juliusolsson05/agent-code once this lands (noted in its Part 4 PR).
🤖 Generated with Claude Code