Skip to content

Delegated child reads the stale shared provider mode in getEnvironmentDetails and presentAssistantMessage #1623

Description

@edelauna

Summary

When a parent task delegates a child in a different mode, two runtime paths read the shared provider mode instead of the task-local mode. The child environment text reports the parent mode. Tool validation receives the parent mode and rejects tools that the child mode allows. The UI, the persisted history item, the system prompt, and the native tool schema all correctly show the child mode. Only these two readers diverge.

Steps to reproduce

  1. Define a custom mode review whose groups include a group the parent lacks, for example edit.
  2. Start a parent task in orchestrator mode.
  3. Approve a new_task delegation to review.
  4. Ask the child to use a Review-only tool.
  5. Read the Current Mode block of the child request.
  6. The tool call fails with: Tool "apply_diff" is not allowed in this mode.

Expected behavior

The environment text reports review. Tool validation receives review and allows Review tools.

Actual behavior

The environment text reports orchestrator. Tool validation receives orchestrator and rejects the Review tool.

Root cause

Commit b89962460319ade787888316a5076211dc07aec9 (PR #1494, merged 2026-09-10, first shipped in v3.82.1) removed handleModeSwitch from the delegation flow. Delegation now passes an explicit handoffExecutionContext and stores the mode on the task. Two legacy readers still read the shared provider mode:

  • src/core/environment/getEnvironmentDetails.ts lines 207 to 225. The function destructures mode from provider state and prints it into the Current Mode block.
  • src/core/assistant-message/presentAssistantMessage.ts line 346 reads provider state. Line 620 passes that mode to validateToolUse().

Before the regression, delegation switched the shared mode. Both readers stayed correct by accident. git blame confirms the defective lines are inherited and unchanged. The task-local pattern already exists at src/core/task/Task.ts line 816 (getTaskMode()). Request construction and prompt building use it. That is why the tool schema says review while validation says orchestrator.

Regression range

Test gaps

  • src/core/environment/__tests__/getEnvironmentDetails.spec.ts seeds mode code and never sets a divergent task mode. It pins the current behavior.
  • src/core/assistant-message/__tests__/presentAssistantMessage-tool-usage-attribution.spec.ts mocks validateToolUse and never asserts the mode argument.
  • The three suites that own this behavior pass while the defect exists: 3 files, 35 tests, all green.

Suggested fix

  1. In getEnvironmentDetails.ts, read the mode through cline.getTaskMode(). Keep custom mode definitions from provider state.
  2. In presentAssistantMessage.ts, pass the task-local mode to validateToolUse().
  3. Add a regression test with provider mode orchestrator and task mode review. Assert the environment text reports review. Assert validateToolUse receives review. Assert edit tools stay blocked in review mode.
  4. Follow-up audit of the SkillTool, RunSlashCommandTool, and MCP restriction modules for the same shared-mode read pattern.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions