Repository navigation
fix(server): a Claude 403 no longer tells you to log in again - #15872
Conversation
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This is a focused fix that shows Claude's permission-denied text for HTTP 403 responses while preserving existing handling for other authentication failures, with a matching regression test. Because it changes authentication-failure handling and user guidance, it requires human review under the applicable safety criteria. No code changes detected at You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
636855c to
e2355c0
Compare
Dismissing prior approval to re-evaluate e2355c0
ce0beaa to
d20dbc1
Compare
The Claude CLI labels a 403 (for example an organization without access to the model) authentication_failed, so T3 showed "Claude could not authenticate, run `claude auth login`". Logging in can't fix a permission error. A 403 now shows the CLI's own text. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
d20dbc1 to
d359e2b
Compare
## What's Changed * chore(deps): Effect 4.0.4 and OpenCode 2.0.28, dropping the patches they made unnecessary by @juliusmarminge in pingdotgg/t3code#19213 * fix(server): a Claude 403 no longer tells you to log in again by @shivamhwp in pingdotgg/t3code#15872 * fix(server): persist only changed pull request links by @juliusmarminge in pingdotgg/t3code#19248 * fix(server): delegate_task explains that supervised runtime modes pause the child by @saphid in pingdotgg/t3code#14416 * fix(server): Claude subagent progress no longer re-stores the unchanged prompt by @Gigioxx in pingdotgg/t3code#18375 * fix(server): thread list reads no longer freeze the server on large databases by @t3dotgg in pingdotgg/t3code#19226 * perf(server): streamed events no longer rewrite the whole thread row by @Baker-Harrison in pingdotgg/t3code#18890 * docs: close PRs written by Gemini or Muse Wonder by @t3dotgg in pingdotgg/t3code#19286 * fix: update all no longer runs agents twice or loses background work by @t3dotgg in pingdotgg/t3code#19291 * fix(server): enforce one database owner and guard update rollback by @maria-rcks in pingdotgg/t3code#16102 * perf(server): reuse stored turn item positions by @tannerpolley in pingdotgg/t3code#19230 * perf(server): avoid quadratic resource history replay by @saphid in pingdotgg/t3code#18825 * fix(server): repair ownership UUID generation by @t3dotgg in pingdotgg/t3code#19298 * fix(client-runtime): slow config snapshots no longer drop working connections by @saphid in pingdotgg/t3code#14518 * fix(server): bound activity publishes so stalled responses release the worker by @saphid in pingdotgg/t3code#18830 * perf(shared): cached SQLite statements no longer hold large parameters by @t3dotgg in pingdotgg/t3code#19305 * fix(provider-cursor): Cursor text generation no longer leaks SQLite file handles on every call by @t3dotgg in pingdotgg/t3code#19310 * fix(server): make SQLite checkpoints durable on macOS by @t3dotgg in pingdotgg/t3code#19304 * perf(server): Codex plan streaming no longer commits every token by @t3dotgg in pingdotgg/t3code#19317 * fix(server): large file edits no longer store their full diff twice by @t3dotgg in pingdotgg/t3code#19316 * fix(web): settings save again after a stored value fails decode by @t3dotgg in pingdotgg/t3code#19312 * fix(server): HTML and Markdown attachments no longer fail OpenCode turns by @t3dotgg in pingdotgg/t3code#19319 * fix(server): worktree paths no longer vanish on git before 2.36 by @t3dotgg in pingdotgg/t3code#19315 * fix(acp): custom models now reach the agent instead of failing to open by @t3dotgg in pingdotgg/t3code#19313 * fix(server): Claude no longer shows unavailable when its health check can't run in $HOME by @t3dotgg in pingdotgg/t3code#19320 * fix(server): stalled OAuth token requests no longer block credential calls by @t3dotgg in pingdotgg/t3code#19321 * fix(server): steered Claude turns no longer undercount token usage by @t3dotgg in pingdotgg/t3code#19314 * fix(server): closing a Claude session no longer leaves plugin MCP servers running by @t3dotgg in pingdotgg/t3code#19322 * fix(client-runtime): T3 Connect link timeouts explain the relay 504 by @t3dotgg in pingdotgg/t3code#19329 * fix(web): settle shortcut moves to the next thread like the sidebar by @t3dotgg in pingdotgg/t3code#19328 * fix(acp): Copilot's default agent no longer disappears from the Agent menu by @t3dotgg in pingdotgg/t3code#19330 * perf(server): SQLite checkpoints no longer block the event loop by @t3dotgg in pingdotgg/t3code#19324 * fix(mobile): incompatible environments now say whether to update the app or the host by @t3dotgg in pingdotgg/t3code#19331 * fix(web): live reasoning stays scrolled to the newest text while it streams by @t3dotgg in pingdotgg/t3code#19334 * fix(server): T3 Connect no longer stays down after a network change by @t3dotgg in pingdotgg/t3code#19335 * fix(clients): host images say when the connection lacks file access by @t3dotgg in pingdotgg/t3code#19337 * fix(clients): a resumed subagent no longer moves the later turn's Worked for row by @t3dotgg in pingdotgg/t3code#19338 * fix: Claude and Codex no longer time out behind mise wrappers by @t3dotgg in pingdotgg/t3code#19340 * perf(server): turns no longer re-read merged PRs from GitHub by @t3dotgg in pingdotgg/t3code#19344 * docs(settings): explain that provider update checks also gate the model catalog by @fixfon in pingdotgg/t3code#18208 * fix(web): an unsaved citation comment survives a question or approval by @t3dotgg in pingdotgg/t3code#19350 * fix(server): changing Claude effort no longer fails while background agents run by @t3dotgg in pingdotgg/t3code#19341 * fix(server): service updates no longer fail on full disks or large databases by @t3dotgg in pingdotgg/t3code#19311 ## New Contributors * @Baker-Harrison made their first contribution in pingdotgg/t3code#18890 * @tannerpolley made their first contribution in pingdotgg/t3code#19230 **Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261014.3093...v0.0.46-nightly.20261014.3105 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261014.3105
## What's Changed * chore(deps): Effect 4.0.4 and OpenCode 2.0.28, dropping the patches they made unnecessary by @juliusmarminge in pingdotgg/t3code#19213 * fix(server): a Claude 403 no longer tells you to log in again by @shivamhwp in pingdotgg/t3code#15872 * fix(server): persist only changed pull request links by @juliusmarminge in pingdotgg/t3code#19248 * fix(server): delegate_task explains that supervised runtime modes pause the child by @saphid in pingdotgg/t3code#14416 * fix(server): Claude subagent progress no longer re-stores the unchanged prompt by @Gigioxx in pingdotgg/t3code#18375 * fix(server): thread list reads no longer freeze the server on large databases by @t3dotgg in pingdotgg/t3code#19226 * perf(server): streamed events no longer rewrite the whole thread row by @Baker-Harrison in pingdotgg/t3code#18890 * docs: close PRs written by Gemini or Muse Wonder by @t3dotgg in pingdotgg/t3code#19286 * fix: update all no longer runs agents twice or loses background work by @t3dotgg in pingdotgg/t3code#19291 * fix(server): enforce one database owner and guard update rollback by @maria-rcks in pingdotgg/t3code#16102 * perf(server): reuse stored turn item positions by @tannerpolley in pingdotgg/t3code#19230 * perf(server): avoid quadratic resource history replay by @saphid in pingdotgg/t3code#18825 * fix(server): repair ownership UUID generation by @t3dotgg in pingdotgg/t3code#19298 * fix(client-runtime): slow config snapshots no longer drop working connections by @saphid in pingdotgg/t3code#14518 * fix(server): bound activity publishes so stalled responses release the worker by @saphid in pingdotgg/t3code#18830 * perf(shared): cached SQLite statements no longer hold large parameters by @t3dotgg in pingdotgg/t3code#19305 * fix(provider-cursor): Cursor text generation no longer leaks SQLite file handles on every call by @t3dotgg in pingdotgg/t3code#19310 * fix(server): make SQLite checkpoints durable on macOS by @t3dotgg in pingdotgg/t3code#19304 * perf(server): Codex plan streaming no longer commits every token by @t3dotgg in pingdotgg/t3code#19317 * fix(server): large file edits no longer store their full diff twice by @t3dotgg in pingdotgg/t3code#19316 * fix(web): settings save again after a stored value fails decode by @t3dotgg in pingdotgg/t3code#19312 * fix(server): HTML and Markdown attachments no longer fail OpenCode turns by @t3dotgg in pingdotgg/t3code#19319 * fix(server): worktree paths no longer vanish on git before 2.36 by @t3dotgg in pingdotgg/t3code#19315 * fix(acp): custom models now reach the agent instead of failing to open by @t3dotgg in pingdotgg/t3code#19313 * fix(server): Claude no longer shows unavailable when its health check can't run in $HOME by @t3dotgg in pingdotgg/t3code#19320 * fix(server): stalled OAuth token requests no longer block credential calls by @t3dotgg in pingdotgg/t3code#19321 * fix(server): steered Claude turns no longer undercount token usage by @t3dotgg in pingdotgg/t3code#19314 * fix(server): closing a Claude session no longer leaves plugin MCP servers running by @t3dotgg in pingdotgg/t3code#19322 * fix(client-runtime): T3 Connect link timeouts explain the relay 504 by @t3dotgg in pingdotgg/t3code#19329 * fix(web): settle shortcut moves to the next thread like the sidebar by @t3dotgg in pingdotgg/t3code#19328 * fix(acp): Copilot's default agent no longer disappears from the Agent menu by @t3dotgg in pingdotgg/t3code#19330 * perf(server): SQLite checkpoints no longer block the event loop by @t3dotgg in pingdotgg/t3code#19324 * fix(mobile): incompatible environments now say whether to update the app or the host by @t3dotgg in pingdotgg/t3code#19331 * fix(web): live reasoning stays scrolled to the newest text while it streams by @t3dotgg in pingdotgg/t3code#19334 * fix(server): T3 Connect no longer stays down after a network change by @t3dotgg in pingdotgg/t3code#19335 * fix(clients): host images say when the connection lacks file access by @t3dotgg in pingdotgg/t3code#19337 * fix(clients): a resumed subagent no longer moves the later turn's Worked for row by @t3dotgg in pingdotgg/t3code#19338 * fix: Claude and Codex no longer time out behind mise wrappers by @t3dotgg in pingdotgg/t3code#19340 * perf(server): turns no longer re-read merged PRs from GitHub by @t3dotgg in pingdotgg/t3code#19344 * docs(settings): explain that provider update checks also gate the model catalog by @fixfon in pingdotgg/t3code#18208 * fix(web): an unsaved citation comment survives a question or approval by @t3dotgg in pingdotgg/t3code#19350 * fix(server): changing Claude effort no longer fails while background agents run by @t3dotgg in pingdotgg/t3code#19341 * fix(server): service updates no longer fail on full disks or large databases by @t3dotgg in pingdotgg/t3code#19311 ## New Contributors * @Baker-Harrison made their first contribution in pingdotgg/t3code#18890 * @tannerpolley made their first contribution in pingdotgg/t3code#19230 **Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261014.3093...v0.0.46-nightly.20261014.3105 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261014.3105
Merges `pingdotgg/t3code` `e536bfd33b` (106 commits since `6002c5c68c`) into the fork. One merge commit; nothing stacked. ## Merge summary - **Landed:** 475 files against 476 in the upstream range. The one missing is `package.json`: its only upstream change was the `tsc-rs` 0.7.0 bump, which the fork drops (`root-package-json`). The fork delta is 809 files. - **Conflicts (5):** - `package.json`: dropped the `tsc-rs` bump. - `pnpm-lock.yaml`: stripped the `tsc-rs@0.7.0` entries from upstream's copy and re-derived it. - `Sidebar.tsx`: kept the fork's thread-list filter and took upstream's new `useSidebarProjectGroups` hook. That hook sorts project groups by all thread shells, not by the filtered list. - `SettingsPanels.tsx`: kept the `serverBehaviorSettings` gate and took upstream's new description. - `threadShell.ts`: kept the fork's subagent predicate and took upstream's `subagentRequests` argument. - **Fix after the merge:** upstream's new `useProjectScriptSettings.test.tsx` used `previewUrl`/`autoOpenPreview`. I changed it to the fork's `port`. - **Unsupported methods:** nothing to add or drop. `vcs.switchRef` and `git.preparePullRequestThread` stay as they are. - **Verification:** `verify.mjs` passes every check except `test`: - duplicate-adds, tripwires, resolution-check, lockfile, fmt, lint, typecheck (re-run after the fix) and build all pass. - Six test files fail on their own, all because of the sandbox: - the five recorded in earlier merges: `AgentScope` (`oom_score_adj`), `ServerBrowserPage` (no Playwright browser), `AcpAdapterV2`, `OrchestratorReplayFixtures`, `OpenCodeServerLedger`; - one new: `@t3tools/ssh` `tunnel.test.ts` from upstream pingdotgg#19432. It fails the same way `AcpAdapterV2` does: a killed process is never reaped, so it still reads as alive. The fork does not touch `packages/ssh`. - `@t3tools/web` tests pass after the fix. - Details are in `docs/fork/upstream-merge-log.md`. `docs/fork/gaps.md` has new notes under five existing entries: capabilities, settlement rules, pull request link, Orchestrator V2 (transcript read) and runtime fixes. ## Usable as-is - Waiting status icon and elapsed timer in the sidebar (pingdotgg#19617) - The settle shortcut moves on to the next thread, the same way the sidebar does (pingdotgg#19328) - Terminal resize, recorded-shortcut save, a keybindings page that prompts to connect, and settings that save after a stored value fails to decode (pingdotgg#19395, pingdotgg#19365, pingdotgg#19400, pingdotgg#19312) - The Mermaid code toggle stays in place, cursor stops stay outside styled markers, and live reasoning stays scrolled while it streams (pingdotgg#19601, pingdotgg#19651, pingdotgg#19334) - PR filters hide Scratch and the project filter follows sidebar order; `#` suggestions include the thread's PRs; merged PRs are no longer re-read every minute (pingdotgg#19179, pingdotgg#19180, pingdotgg#19357, pingdotgg#19374) - New provider-update-checks copy (pingdotgg#18208), shown only where the fork's `serverBehaviorSettings` gate already shows that row - Dependency bumps: Effect 4.0.4, OpenCode 2.0.28. `tsc-rs` 0.7.0 is deliberately dropped. ## Unsupported in Moatless / needs implementation - **Auto-settle keeps threads with a PR** (pingdotgg#14642): adds the `sidebarAutoSettleKeepPullRequests` setting and the `threadAutoSettlementScope` capability. Moatless does not report the capability, so the row stays hidden. - **Settled-worktree cleanup** (pingdotgg#15208): adds the `worktreeSettledAfterDays` setting and the `settledWorktreeCleanup` capability (Storage settings). Not reported, so the row is hidden. - **Thread transcript HTTP read** (pingdotgg#15210): `GET /api/orchestration/threads/:threadId/transcript`, used only for a thread dropped in from another environment. Moatless does not route it, and a single-environment deployment cannot reach it. - **`thread.pull-request-link-updated` event** (pingdotgg#19248): Moatless sends no pull-request frames; it changes the listing instead. - **Delegated-task question handling**: `hasPendingQuestion` on the orchestrator MCP task result (pingdotgg#18459, pingdotgg#19521, pingdotgg#19538). - T3 Connect revoked links, SSH and Tailscale, pairing, and desktop- and mobile-only items: not used by the Moatless web client. ## Backend behavior to consider reproducing in Moatless - Inactivity auto-settle that skips PR-linked threads (pingdotgg#14642); settled and idle-released threads stop reading as Waiting (pingdotgg#19355) - A retention sweep for settled threads' workspaces (pingdotgg#15208, pingdotgg#19418) - Store a PR link only when it changes, and stop re-reading merged PRs each turn (pingdotgg#19248, pingdotgg#19344) - GitHub reviewers include requested teams (pingdotgg#19375); new worktrees survive a concurrent fetch (pingdotgg#19411) - Commit and title generation fall back to the custom model (pingdotgg#19386) - Claude: `managed-mcp.json` is honoured and a 403 no longer says to log in (pingdotgg#18706, pingdotgg#15872) - Codex: "Always allow this session" works and slow MCP servers no longer drop tools (pingdotgg#19635, pingdotgg#19368) - CLIs behind mise wrappers no longer time out (pingdotgg#19340); cold usage scans stop stalling the server (pingdotgg#19446); a single database owner is enforced, with exit code 78 (pingdotgg#16102) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Moatless task: https://moatless.soaplabstest.com/tasks/4979b4c3-e4cc-4911-849b-adb94cb65be6
A Claude turn that fails with a 403, for example "Your organization does not have access to this model", showed "Claude could not authenticate. For subscription login, run
claude auth login...". Logging in again can't fix a permission error, so the message sends people the wrong way.The Claude CLI marks a 403 as
authentication_failed, the same label it uses for a 401, and T3 replaced the result with its sign-in message. A 403 result now shows the CLI's own text instead. A 401 and a missing login keep the sign-in message.This is a small fix for an obvious bug under the contributing guide: the wrong advice comes from one label, and the change only affects results with
api_error_status403.Testing
I ran an isolated dev server from this branch with a copy of real data and the real web client. A Claude instance pointed
ANTHROPIC_BASE_URLat a local fake Anthropic API that answers every request with 403permission_error"Your organization does not have access to this model." The realclaudeCLI 2.1.288 produced:main)Before, the card said to run
claude auth login. After, it shows the CLI's text with the 403 reason, and the run still ends as failed with codeapi_error_403.Checks:
vp test run apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts: 136 passed. The new test feeds the CLI's 403 frames and fails onmainwith the sign-in message. It passed 10 runs in a row. The existing expired-login test still expects the sign-in message.tsc --noEmitinapps/server: passes. Lint on the changed files: no new findings.The CLI's text still starts with "Failed to authenticate." That's the CLI's wording, and T3 shows it as is.
#14891 edits the same
failureHintlines to keep the CLI's error text for other API errors. The two don't depend on each other, and whichever lands second needs a small rebase.Made by Claude Opus 5.5 in Claude Code, run from T3 Code.
🤖 Generated with Claude Code