Repeated t3_thread_read approvals after session approval in Claude Plan mode with Full access#23918

opened23d agobyLluquibu

What happened

While using Claude in T3 Code Desktop with Full access selected and Plan enabled, reading another thread repeatedly displayed Command approval cards for mcp__t3-code__t3_thread_read.

Requests occurred while paging through messages, activity, and truncated item text. Session approval did not prevent later requests in the observed turn.

Diagnosis

Source inspected at v0.1.2, commit 044f07257c9684ae4543bd1e1ebf9c394e9e3830:

These facts identify the permission path but do not establish why Claude requested approval again. SDK decision reasons, effective permission rules, process continuity, and subagent attribution were not captured.

Steps to reproduce

Suggested minimal reproduction, not yet executed in isolation:

  1. Create two test threads with enough dummy text to require pagination.
  2. In the source thread, select Claude, Full access, and Plan before starting a turn.
  3. Ask Claude to read the other thread, continuing through pages and truncated items.
  4. On a t3_thread_read approval card, select Always allow this session.
  5. Observe subsequent calls using afterPosition or itemId/textOffset.

Expected: an authorized history-reading workflow can continue within the stated permission scope, with any additional authorization explained.

Observed in the real session: repeated approval requests, including requests created after session approval.

Version

Affected Desktop version reported: 0.1.2. The local server also reports 0.1.2. Triage CLI version only: 0.1.2-nightly.20261022.3541.

Environment

Windows x64, build 10.0.26200. T3 Code Desktop Beta, Claude Agent provider, affected run model claude-opus-5-5. Effective Claude CLI and Agent SDK versions were not established.

Evidence

shell
1Read-only SQLite inspection found, for one affected run:
2
3tool: mcp__t3-code__t3_thread_read
4distinct approval requests: 19
5request kind: command
6recorded decisions:
7 accept: 9
8 acceptForSession: 10
9requests created after the first acceptForSession resolved: 17
10distinct recorded providerThreadId values: 1
11distinct recorded providerTurnId values: 1
12
13These identifiers do not establish that all calls used the same Claude process. The original report counted 17 requests in a narrower history window.

No exact duplicate found in the searches performed. https://github.com/pingdotgg/t3code/issues/4974 concerns Auto mode outside Plan. https://github.com/pingdotgg/t3code/issues/3744 concerns side effects executing before plan approval.

Fix applied or workaround

No fix applied. Session approval was used in the incident and is not a verified workaround. No correction for this exact symptom was confirmed in the upstream sources reviewed.

No permissions, service state, source code, or database contents were changed during triage.

Filed by

Codex, GPT-6, via t3 triage.

Synced from GitHub

Same here on Windows 11, T3 Code 0.1.3-nightly.20261023.3553, Claude Code 2.1.309, Full access + Plan. Since the 2026-10-20 nightly, every MCP call and every shell command Claude Code can't classify as read-only shows an approval card. Read and plain ls/grep still run.

As far as I can tell this comes from #17963: in Plan, the adapter now always installs the permission callback, and Claude Code's plan mode sends it anything not auto-approved, not only writes. Allow rules in ~/.claude/settings.json work around it for shell commands, but not for MCP tools: in plan mode Claude Code sends any MCP tool without a read-only annotation to the callback even when an allow rule matches, so those cards can't be silenced from the user side.

Can you please retract that change and reconsider the mechanics - in the current implementation it became absolutely unusable for automated runs.

Synced from GitHub

Still happens on v0.1.5 (Stable); the issue was filed on 0.1.2. T3 Code Desktop on Windows x64; the local server reports 0.1.5. Claude provider, model claude-fable-5-1 (Extra High), Full access + Plan, Claude Code CLI 2.1.314 (version reported by the SDK init event).

From one affected run (read-only SQLite and the provider event log):

  • The SDK session was opened with permissionMode: "plan" and allowedTools: ["mcp__t3-code__*"], yet every mcp__t3-code__t3_thread_read call still reached the approval callback.
  • 15 approval requests, all for t3_thread_read, created 18:03–18:14 UTC in one run. Decisions: 9 accept, 6 acceptForSession. 13 requests were created after the first acceptForSession resolved.
  • Session approval also fails without subagents: the first 4 calls came from the parent agent (parent_tool_use_id: null), and 2 of them were created after the parent's own session approval had resolved.
  • The other 11 calls came from two Agent-tool subagents running in parallel (6 and 5 by parent_tool_use_id). Session approvals given on subagent calls did not stop later prompts either.

After switching the thread out of Plan (still Full access), the next run raised no command approvals, but it made no t3_thread_read calls, so leaving Plan is not confirmed as a workaround here. As noted above, allow rules do not cover MCP tools in Plan.

On #24413: neither v0.1.5 nor current main contains it or an equivalent change. Its live check paged with a single agent, so the parallel-subagent case above may be worth a test. CodeRabbit's open review comment there suggests excluding MCP tools from the session-grant cache; since t3_thread_read is an MCP tool, adopting that as written would leave this issue unfixed.

Produced by Claude Code (Claude Opus 5.5) via t3 triage.

Synced from GitHub

Yep I also confirm that - extremely annoying!

Synced from GitHub

Plan mode with Claude in T3 Code is unusable right now. Please fix this as soon as possible. With Full access + Plan, every call to an MCP tool without a read-only hint stops on an approval card, and "Always allow this session" doesn't stop the next one. A Full access thread where Claude enters plan mode by itself is worse, because every new shell command the CLI can't prove read-only also asks.

I tracked it down with a probe. It uses the same SDK, launches the same claude binary T3 launches, and answers every canUseTool call the way the adapter answers acceptForSession (permissionResultFromDecision plus toSessionPermissionUpdates). The MCP tool is an in-process SDK tool without readOnlyHint. Bash goes through a PreToolUse hook that rewrites cat to rtk read. The probe calls rtk --version and the MCP tool twice each, so the second call shows whether the session approval held.

Versions are T3 Code 0.1.7-nightly.20261103.4119 (cefb544af3), Claude Code 2.1.317 and @anthropic-ai/claude-agent-sdk 0.3.284 on Windows 11.

Query optionsBash the CLI can't prove read-onlyMCP tool without readOnlyHint
permissionMode: "plan" (T3 Plan + Full access)runs, no callbackcallback on both calls
"plan" + allowDangerouslySkipPermissionsruns, no callbackcallback on both calls
"bypassPermissions", then Claude calls EnterPlanModecallback for each new command, the repeat runscallback on both calls
"bypassPermissions" + permissions.ask for both toolscallback on both callscallback on both calls

The last row is expected because ask rules always prompt. The first three rows are the bug.

Session approval doesn't stick because the CLI sends no suggestions for the MCP ask in plan mode. The adapter then falls back to addRules [{ toolName }] with destination: "session", and the CLI still asks on the next call, so that rule has no effect in plan mode. Bash asks come with a suggestion such as Bash(rtk read *) or Bash(rtk --version), and those rules do stick.

The terminal doesn't show this because Claude Code 2.1.317 treats plan mode like bypass only in interactive sessions. The minified check is e==="plan"&&n===!0&&!he(), where he() is !launchOptions.isInteractive(), and the permissions docs say the same ("interactive terminal sessions in plan mode with bypass permissions available"). T3 runs the CLI with stream-json and --permission-prompt-tool stdio, so plan mode is always strict there, and row 2 shows that --allow-dangerously-skip-permissions doesn't change it. The adapter has to keep the session grants itself.

#24413 does that, but its guard lets ask rules through. It reads matchedAskRule === undefined as "no ask rule", and in row 4 the ask-rule callbacks arrived with no matchedAskRule, no decisionReason and no suggestions, in bypass and after EnterPlanMode alike. After one session approval, #24413 would auto-allow a tool the user put in permissions.ask. Since #21806 the adapter reads the effective Claude settings for the turn's directory, so it could check the ask list there.

Row 3 has two more problems. Since #21806, requiresClaudeApproval is true for every callback under bypass, so after Claude enters plan mode by itself each ordinary command becomes a card until #15224 restores bypass on the next turn. The card then says Full access only stops for safety checks it can't skip. That text (#22546) comes from the requested mode, not the mode the CLI reports. Plain ask-rule cards get the same "safety check" text because they carry no matchedAskRule, while the safety-check cards I've seen have a specific decisionReason, such as "A variable in this command can't be checked before it runs".