[BUG] `claude remote-control` (server mode) fails registration with 400 on legacy `/v1/environments/bridge`, while `--remote-control` succeeds via v2 session path
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
What's Wrong?
claude remote-control (server mode) fails immediately at the registration phase with Error: Registration: Failed with status 400. No session URL or QR code is ever produced.
On the same machine, same account, same directory, and same binary, both claude --remote-control (interactive) and /remote-control (from an existing session) connect successfully.
Debug logs show the two modes use different protocol paths:
- Server mode registers a v1 environment:
[bridge:api] POST /v1/environments/bridge → 400 - Interactive mode never calls that endpoint. It creates a session and builds a v2 transport:
[remote-bridge] Created session cse_... → v2 session URL: /v1/code/sessions/cse_...
This suggests server mode still uses the legacy environment-registration endpoint while interactive mode has been migrated to the v2 session flow, and the legacy endpoint now rejects the client's registration body.
Secondary defect: the CLI does not log the 400 response body, only the outbound POST. The server's rejection reason is invisible even with --debug-file, which makes the failure undiagnosable without proxy-level capture.
What Should Happen?
claude remote-control should register successfully and serve on-demand sessions, as documented at https://code.claude.com/docs/en/remote-control — printing a session URL and QR code, then waiting for remote connections.
Failing that, the error should surface the server's rejection reason rather than a bare status code.
Error Messages/Logs
# Terminal output (identical across all flag combinations tried)
$ claude remote-control
Error: Registration: Failed with status 400
# Server mode debug log (fails)
[DEBUG] [bridge:init] bridgeId=c2805383-... dir=/home/<user>/<project> branch=feature/rfc-0010 gitRepoUrl=git@github.com:<org>/<repo> machine=home-pc
[DEBUG] [bridge:init] apiBaseUrl=https://api.anthropic.com sessionIngressUrl=https://api.anthropic.com
[DEBUG] [bridge:init] sandbox=false debugFile=/tmp/rc-server.log
[DEBUG] [bridge:api] POST /v1/environments/bridge bridgeId=c2805383-...
[DEBUG] Released PID lock for 2.1.222
# No response line is logged. The process exits immediately after the POST.
# Interactive mode debug log (works), same directory
[DEBUG] [remote-bridge] Created session cse_01J4Lz...
[DEBUG] [remote-bridge] Fetched bridge credentials (expires_in=28800s)
[DEBUG] [remote-bridge] v2 session URL: https://api.anthropic.com/v1/code/sessions/cse_01J4Lz...
[DEBUG] [bridge:repl] CCR v2: worker sessionId=[REDACTED] epoch=1 (from /bridge)
[DEBUG] [remote-bridge] v2 transport created (epoch=1)
[DEBUG] [bridge:repl] handleStateChange state=ready detail="undefined" cancelled=true outboundOnly=false
Steps to Reproduce
- Authenticate with a claude.ai account:
claude auth login(API key auth is not supported for Remote Control) - Create an empty non-git directory to rule out repository metadata:
mkdir /tmp/rc-test && cd /tmp/rc-test - Run
claude remote-control - Observed:
Error: Registration: Failed with status 400, process exits immediately - In the same directory, run
claude --remote-control - Observed: succeeds, prints a session URL and QR code, session appears in the Code tab of the Claude app
No project files, configuration, or repository state are required — step 2 uses an empty directory and reproduces identically to a real project.
To capture the logs above, add --debug-file /tmp/rc-server.log to step 3 and --debug-file /tmp/rc-int.log to step 5, then:
diff <(grep bridge /tmp/rc-server.log) <(grep bridge /tmp/rc-int.log)
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.222 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
VS Code integrated terminal
Additional Information
Environment
- Platform: linux-x64
- Install method: native (
~/.local/share/claude/versions/2.1.222) - Auth: claude.ai OAuth — interactive Remote Control works, so credentials and scopes are valid
- Plan: Max
ANTHROPIC_BASE_URLunset; no Bedrock/Vertex/Foundry variables set- No feature-flag-disabling variables set (
DISABLE_TELEMETRY,DO_NOT_TRACK,CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC,DISABLE_GROWTHBOOK)
claude doctor output
Claude Code doctor
Running: native (2.1.222)
Commit: fbf49312c284
Platform: linux-x64
Path: /home/<user>/.local/share/claude/versions/2.1.222
Config install method: native
Search: OK (bundled)
Auto-updates: enabled
Auto-update channel: latest
Last update attempt: success → 2.1.222 (2026-08-05)
Remote Control
Control this session from claude.ai/code or the Claude mobile app
No installation issues found.
Ruled out
- Git metadata — reproduces identically in a fresh non-git directory, where no
git_repo_urlis sent - Registration payload fields — identical 400 across
--capacity 1,--capacity 2,--spawn session, and--name "test" --capacity 1, so neithermax_sessionsnor the auto-generated hostname-based name is the rejected field - Auth / scopes / plan eligibility — interactive Remote Control works on the same credentials; the failure is 400, not 401/403
- Stale environments — no orphaned Remote Control sessions listed at claude.ai/code
- Version staleness — on latest (2.1.222);
claude updatereports up to date - Environment variables — none of the documented Remote Control blockers are set
Suggested fixes
- Migrate server mode to the same v2 session path interactive mode uses, or fix the legacy endpoint's handling of the server-mode registration body
- Log the response body on registration failure so the rejection reason is visible with
--debug-file
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗