`AskQuestion` tool can return synthetic skip string with highly variable, unpredictable delay

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Cursor version: 3.1.15
OS: Windows 10.0.26200
Model used during observations: Opus 4.7

Summary

The AskQuestion tool occasionally resolves a pending dialog with the exact tool-return string

Questions skipped by the user, continue with the information you already have

without any user interaction. The agent cannot distinguish this from a real user skip, which has caused agents to proceed past questions that were never answered.

The delay before the synthetic skip fires varies from ~44 seconds to ~3 hours, and is not correlated with local state (OS sleep, Cursor focus, or user activity).

Impact

Because the synthetic skip is byte-identical to a deliberate user skip, agents treat it as user consent by default. For destructive or high-impact prompts (file deletions, migrations, destructive git commands, etc.) this is a safety issue. Workarounds in custom rules can soften it, but only if the agent recognizes the ambiguity — which requires explicit instructions that most users won’t have.

What I observed

One overnight AFK session produced a skip in ~44 seconds for a single AskQuestion call carrying 4 questions. The dialog UI remained visible on screen after the fact; the agent had already received the skip string and moved on.

To characterize the trigger, I ran a controlled battery of 8 probes (2 runs Ă— 4 payload shapes) over ~15 wall-clock hours in a single chat, with timestamps via Get-Date. No human interaction with any dialog (aside from one text-entry test in R1-T1, which never reached the agent). Every probe returned the exact skip string.

Probe Shape Delay before skip
R1-T1 4 single-select Qs 2h 35m 29s
R1-T2 2 single-select Qs 18m 28s
R1-T3 1 Q, long payload 20m 30s
R1-T4 4 multi-select Qs 3h 17m 24s
R2-T1 4 single-select Qs 1h 39m 09s
R2-T2 2 single-select Qs 2h 19m 49s
R2-T3 1 Q, long payload 2h 19m 06s
R2-T4 4 multi-select Qs 2h 03m 24s

Same-shape probes differ by up to 7.6Ă— across the two runs (R1-T2 vs R2-T2: 18m vs 2h 20m), so payload shape is not the driver.

Critical: the synthetic skip can fire while the user is actively interacting with the dialog

In at least one reproduced instance, the skip string was returned to the agent while I was actively filling in answers to the questions — Cursor focused, the question dialog focused, mid-typing. My eventual Continue click presumably submitted against a dialog that had already been resolved server-side, so my answers were silently discarded and the agent proceeded as if I had skipped.

This means dialog-level user interaction does not extend, reset, or communicate “still active” to whatever server-side process resolves these dialogs. There is no client-side behaviour a user can adopt to prevent it.

What the data rules out

  • Not OS sleep / inactivity. R2-T1 and R2-T4 fired while I was actively using the machine.
  • Not Cursor-app idle. If Cursor flipped an “inactive” flag, all queued dialogs would cascade-resolve; instead they resolved hours apart, independently.
  • Not payload shape / question count / payload size. Same shapes produce wildly different delays across runs.
  • Not a fixed inactivity timer. Deltas span nearly two orders of magnitude (18 min to 3h 17m, plus the 44s overnight outlier).

Additional observations that may help

  1. Only the most recently-issued AskQuestion card is visible in the UI at any time. Prior cards disappear entirely from chat history when a new one is issued — they are not just hidden but not recoverable by scrolling. This makes “re-ask via a new AskQuestion” a non-option for agents trying to recover from ambiguous skips.
  2. Typed-but-unsubmitted text in a question’s free-text field never reaches the agent. I entered text in R1-T1’s input, did not click Continue/Skip; agent only received the bare skip string.
  3. The synthetic-skip payload is byte-identical to a deliberate skip. Agents have no signal to distinguish them.

Hypothesis

The trigger is most likely server-side — either a periodic pending-dialog sweep, a websocket reconnect resolving stale state, or backend deployment/restart cleanup. The variability in delay and its independence from local state are consistent with any of these. I have not run DevTools WebSocket capture on the session.

What would help

  1. A distinct tool-return string for timeout vs user-skip (e.g., AskQuestion timed out; user did not respond vs the current Questions skipped by the user…). This alone would let agents handle the two cases safely without custom rules.
  2. If that’s not feasible, publishing the timeout semantics (when does it fire, under what conditions) so rule authors can encode correct fallback behaviour.
  3. Optional: preserve prior AskQuestion cards in chat history rather than purging them when a new one is issued.

Local mitigation I’m using

A .cursor/rules/agent-communication.mdc rule inst

Steps to Reproduce

Have the agent ask you a question. Wait.

Expected Behavior

The agent to wait for my answer, or at the very least to be aware that I didn’t actually click the “Skip” button.

Operating System

Windows 10/11

Version Information

Version: 3.1.15 (system setup)
VSCode Version: 1.105.1
Commit: 3a67af7b780e0bfc8d32aefa96b8ff1cb8817f80
Date: 2026-04-15T01:46:06.515Z
Layout: editor
Build Type: Stable
Release Track: Default
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
V8: 14.2.231.22-electron.0
OS: Windows_NT x64 10.0.26200

For AI issues: which model did you use?

Opus 4.7

Additional Information

I built a workaround by adding a rule that tells agents to log time before asking, specifically ignore the skipped message, log time after asking, and to ignore the skip message and instead re-ask the question as a plain message, and end it’s turn to wait for my answer.

This has so far worked.

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

Hey, thanks for the incredibly detailed report.

We can confirm the bug. In sync mode, AskQuestion creates a blocking Promise on the IDE client side, but unlike the terminal/edit/MCP review handlers, it doesn’t register an abort listener on the gRPC stream. When the connection drops due to an idle timeout (TCP keepalive, TLS session, LB), the pending decision gets orphaned and resolves with an empty result, which then maps to that exact string “Questions skipped by the user…”. The variable delays (44s vs 3h) and the fact it’s independent of local state line up with this.

We’re already tracking this issue on our side (same class of bug). I can’t share an ETA for the fix yet, but I noted your three suggestions, especially having a distinct return string for timeout vs user-skip, and I’ll add them to the ticket along with your repro details. They really help.

On your other observations:

  • New AskQuestion cards covering previous ones, yeah, that’s a separate UX issue and I’ll flag it.
  • Skip triggering while the user is actively typing is the worst case, since the user thinks their answer will go through. That’s the main argument for separating the return strings.

Your workaround via a rule (log time + ignore skip + re-ask) is sensible. I’d keep it enabled until the issue is closed. If we have an update on the fix, I’ll reply in the thread.

Thanks for the workaround! Implemented it for a single workspace only using globs.

globs:

  • “/.cursor//*.mdc”
  • “/.cursor//*.md”
  • “/.cursor//*.json”
  • “**/.cursor/.gitignore”
  • “rules/**/*.mdc”
  • “agents/**/*.md”
  • “skills/**/*.md”
  • “skills-cursor/**/*.md”
  • “hooks/**/*”
    etc.
    alwaysApply: false

My take on the issue:

Description:

I hit a pattern many times (not one-off): the agent ends a turn with AskQuestion (multi-step questionnaire). I am away from the machine or the OS sleeps. The backend appears to treat the dialog as resolved (same class as the already-reported synthetic skip / connection-idle behaviour), and the agent continues, completes file writes, and finishes the run.

After I resume from sleep, the questionnaire is still on screen even though the transcript already shows the agent proceeded (e.g. “The user skipped — proceeding with defaults…”) and disk changes are done. If I answer the questionnaire anyway, the agent tab can remain in Running state with the Stop button visible, as if a turn were still in flight—despite the substantive work having completed.

This is a UX / state-machine bug: the client should either (a) dismiss superseded AskQuestion UI when the server has already resolved the prompt, (b) block late submits with a clear “this prompt already closed” message, or (c) reconcile late answers without leaving the session wedged in Running.


Steps to Reproduce:

  1. Start an Agent session where the model will call AskQuestion before writing to the repo (multi-select / multi-card is enough).

  2. Leave the machine idle until the agent auto-continues (or put Windows to sleep while the question is showing).

  3. Wake / return: confirm the agent already continued (new assistant messages, files changed) while the question UI is still visible.

  4. Optionally submit answers on the stale questionnaire.

  5. Observe whether the tab stays Running with Stop visible indefinitely.


Expected Behavior:

  • If the server has already resolved the prompt (skip, timeout, or synthetic idle resolution), the client removes or clearly disables the questionnaire so the user cannot submit against a closed prompt.

  • The agent tab does not show an active Running / Stop state once the model turn that owned the question has completed—unless a new turn is genuinely executing.

Version Information:

Version: 3.2.11 (user setup)
VSCode Version: 1.105.1
Commit: e9ee1339915a927dfb2df4a836dd9c8337e17cc0
Date: 2026-04-24T14:36:47.933Z
Layout: editor
Build Type: Stable
Release Track: Nightly
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
V8: 14.2.231.22-electron.0
OS: Windows_NT x64 10.0.26220

Additional Information:

Hey, thanks for the extra details. The observations are helpful.

What you’re describing is basically two sides of the same bug: the backend resolves the pending decision (an orphaned promise after the gRPC idle timeout), but the client never finds out. That’s why the questionnaire UI keeps spinning, and a late submit goes nowhere, leaving the tab stuck in Running with Stop. Makes sense that we either need reconciliation (remove or disable the card once the server has already closed the prompt), or we need to handle late submits properly.

I can’t share an ETA for the fix yet. Once we have an update, we’ll post it here.

Thread Addition Request consumed on AskQuestion timeout is relevant too, thanks for the link. I’ve attached it.