Skip to content

CLI: 'ask' permission tier silently auto-denies when onToolPermissionRequest callback isn't wired, mislabeled as user denial #13178

Description

@ComplacencyKillz

Before submitting your bug report

Relevant environment info

  • OS: Linux
  • Continue version (CLI): 1.5.47
  • Node: v22.15.0

Description

Summary

In @continuedev/cli, tool calls with an ask-tier permission policy sometimes get silently denied with no interactive prompt ever shown to the user. The denial is then reported with denialReason:"user", which is misleading — the user was never actually asked.

Root cause (from reading the bundled dist/index.js)

The permission-decision function resolves an ask policy by calling into the prompt-request function:

async function _ua(e,t,n,r){
  let o=VXe(t,e);
  return o.permission==="allow" ? {approved:!0}
    : o.permission==="ask" ?
        (r ? {approved:!1,denialReason:"policy"}
           : await Eua(t,n) ? {approved:!0}
           : {approved:!1,denialReason:"user"})
    : o.permission==="exclude" ? {approved:!1,denialReason:...}
    : ...
}

And the actual prompt function:

async function Eua(e,t){
  if(!t?.onToolPermissionRequest) return !1;
  let n={name:e.name,arguments:e.preprocessResult?.args??e.arguments,preview:e.preprocessResult?.preview, ...};
  ...
}

If t.onToolPermissionRequest is not attached for a given tool call, Eua returns false immediately — no prompt is ever rendered — and the caller reports denialReason:"user" even though the user was never asked.

Steps to reproduce

  1. Run cn interactively (not headless, no -p/--print)
  2. Configure permissions.yaml such that some tool/Bash patterns are unmatched by allow/ask/exclude, falling through to the default "ask" policy
  3. Trigger a tool call matching one of those unmatched patterns (e.g. a Bash command not covered by any allow rule)
  4. Observe: the tool call is denied with no interactive prompt ever appearing, and the denial is reported as if the user rejected it

Expected behavior

An ask-tier permission should always show the interactive prompt when not in headless mode. If the callback isn't available, that's an internal wiring bug and should either surface an error/warning rather than silently denying, or the denial reason should reflect the actual cause (e.g. "callback_missing") instead of being mislabeled "user".

Additional context

We also intermittently saw "Message splitting exceeded maximum iterations, stopping" in the same sessions where this occurred, which may point to broader instability in the TUI's message/callback event loop — possibly a related root cause (the same callback-wiring issue affecting more than just the permission prompt).

Workaround

Expanding permissions.yaml's allow list to explicitly cover the needed command patterns (e.g. Bash(pio*), Bash(ufbt*), Bash(git*)) avoids the broken ask path entirely, since allow short-circuits before Eua is ever called.

Related issues (not duplicates, but adjacent)

To reproduce

See "Steps to reproduce" above.

Log output

N/A — no error is logged; the tool call is simply denied with denialReason:"user" and no prompt is shown.

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