zed-industries/zed · warning

Permission denied: user sent a follow-up message instead of

Error message

Permission denied: user sent a follow-up message instead of approving the tool call.

What it means

When a tool call is awaiting permission and the user sends a new message instead of choosing allow/deny, the pending authorization is interrupted: agent.rs maps RequestPermissionOutcome::InterruptedByFollowUp to a RejectOnce outcome carrying the sentinel option id FOLLOW_UP_PERMISSION_DENIED_OPTION_ID, and ensure_tool_call_authorization_not_interrupted converts that outcome into this error so the tool call ends with a clear reason.

Source

Thrown at crates/agent/src/thread.rs:1163

        acp_thread::PermissionOptions::Dropdown(choices)
    }
}

#[derive(Debug)]
pub struct ToolCallAuthorization {
    pub tool_call: acp::ToolCallUpdate,
    pub options: acp_thread::PermissionOptions,
    pub response: oneshot::Sender<acp_thread::SelectedPermissionOutcome>,
    pub context: Option<ToolPermissionContext>,
    pub kind: acp_thread::AuthorizationKind,
}

fn ensure_tool_call_authorization_not_interrupted(
    outcome: &acp_thread::SelectedPermissionOutcome,
) -> Result<()> {
    if outcome.option_id.0.as_ref() == FOLLOW_UP_PERMISSION_DENIED_OPTION_ID {
        Err(anyhow!(TOOL_CALL_INTERRUPTED_BY_FOLLOW_UP_MESSAGE))
    } else {
        Ok(())
    }
}

fn auto_resolve_permission_outcome(
    options: &acp_thread::PermissionOptions,
    is_allow: bool,
) -> Result<acp_thread::SelectedPermissionOutcome> {
    let kind = if is_allow {
        acp::PermissionOptionKind::AllowOnce
    } else {
        acp::PermissionOptionKind::RejectOnce
    };
    let option = options
        .first_option_of_kind(kind)
        .ok_or_else(|| anyhow!("permission prompt has no auto-resolution option"))?;

View on GitHub (pinned to bc538def45)

Solutions

  1. Re-prompt or re-issue the tool call: the follow-up message becomes the new instructions and the agent can retry the tool.
  2. In UIs, present this as 'superseded by your message', not as a hard failure.
  3. If it appears without user action, audit code paths that push user content while a ToolCallAuthorization is pending.
Defensive patterns

Strategy: try-catch

Try / catch

match ensure_tool_call_authorization_not_interrupted(&outcome) {
    Ok(()) => { /* proceed with the tool call */ }
    Err(e) if e.to_string().contains("follow-up message") => {
        // permission superseded: mark tool call as interrupted, not failed;
        // the agent will re-plan from the user's new message
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: The user types a follow-up message while a permission prompt is pending for a tool call; the synthesized denial then fails the tool call with this message.

Common situations: Users revising instructions mid-approval; permission dialogs left open while the user keeps chatting; automated clients pushing user messages while authorization is outstanding.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/3cca32e909290c66. Report an issue: GitHub.