aaif-goose/goose · error
Cannot update message while prompt is active
Error message
Cannot update message while prompt is active
What it means
Thrown when editing a message that has a pending tool-permission prompt: the code calls acpChatSessionActions.startPromptCancellation(sessionId, attemptId) and expects a cancellation handle back. A null return means the store could not start a cancellation for that prompt attempt — typically because the prompt attempt state changed between reading the snapshot and acting on it (it settled, was restored, or never existed). The edit aborts rather than corrupting prompt state.
Source
Thrown at ui/desktop/src/acp/chatSessionController.ts:286
editSnapshot?.chatState === ChatState.WaitingForUserInput &&
getPendingToolConfirmationIds(editSnapshot?.messages ?? []).size > 0;
const isIdle = editSnapshot?.chatState === ChatState.Idle;
const pendingToolPermissionPromptAttemptId = isPendingToolPermission
? activePromptAttemptId
: undefined;
const canEditInPlace = isIdle || pendingToolPermissionPromptAttemptId != null;
if (!canEditInPlace) {
return;
}
if (pendingToolPermissionPromptAttemptId != null) {
const cancellation = acpChatSessionActions.startPromptCancellation(
sessionId,
pendingToolPermissionPromptAttemptId
);
if (!cancellation) {
throw new Error('Cannot update message while prompt is active');
}
const promptCancellationSettled = acpChatSessionActions.waitForPromptCancellation(
sessionId,
pendingToolPermissionPromptAttemptId
);
try {
await acpCancelPrompt(sessionId);
} catch {
acpChatSessionActions.restorePromptCancellation(
sessionId,
pendingToolPermissionPromptAttemptId
);
throw new Error('Cannot update message because the active prompt could not be cancelled');
}
cancelAcpPermissionRequestsForSession(sessionId);View on GitHub (pinned to 3810898a74)
Solutions
- Re-read the snapshot and retry the edit once — after the race resolves, either the prompt is gone (isIdle path) or the attempt id is current.
- Disable the edit affordance while a permission prompt is being answered elsewhere.
- Make the edit submit path idempotent so a second attempt after this error succeeds.
Example fix
// before
const cancellation = acpChatSessionActions.startPromptCancellation(sessionId, pendingToolPermissionPromptAttemptId);
if (!cancellation) {
throw new Error('Cannot update message while prompt is active');
}
// after (retry once against fresh state, then surface a soft failure)
let cancellation = acpChatSessionActions.startPromptCancellation(sessionId, pendingToolPermissionPromptAttemptId);
if (!cancellation) {
await nextStoreUpdate(sessionId); // wait one store tick
const fresh = acpChatSessionStore.getSnapshot(sessionId);
if (fresh?.chatState === ChatState.Idle) return submitEdit(sessionId, messageId, /* ... */);
throw new Error('Cannot update message while prompt is active');
} Defensive patterns
Strategy: validation
Validate before calling
// Re-check chat state right before submitting the edit
const snapshot = options.getCurrentSnapshot();
const stillPending =
snapshot?.chatState === ChatState.WaitingForUserInput &&
getPendingToolConfirmationIds(snapshot?.messages ?? []).size > 0;
if (!stillPending && snapshot?.chatState !== ChatState.Idle) {
return; // prompt lifecycle changed; retry the interaction instead
} Try / catch
try {
await submitEditedMessage(sessionId, messageId, newContent, retainedImages, options);
} catch (error) {
if (/Cannot update message while prompt is active/.test(String(error))) {
await nextStoreTick();
return submitEditedMessage(sessionId, messageId, newContent, retainedImages, options); // one retry
}
throw error;
} Prevention
- Serialize permission-dialog answers and message edits through one queue per session.
- Read pendingToolPermissionPromptAttemptId from the freshest snapshot at the last possible moment.
- Disable the edit button while a permission prompt is resolving.
When it happens
Trigger: Reading pendingToolPermissionPromptAttemptId from a snapshot, then the permission prompt is answered or cancelled concurrently (user clicks allow/deny in another surface), so startPromptCancellation finds nothing to cancel; stale attempt id after restorePromptCancellation; double-submit of the same edit.
Common situations: User answers a permission dialog at the same moment they submit a message edit; two edit attempts racing; automated tests replaying an edit after the prompt already resolved.
Related errors
- Message with id ${messageId} not found in current messages
- Cannot update message because the active prompt could not be
- ACP URL is not available
- Unknown provider: ${providerId}
- Unsupported extension type for ACP: ${config.type}
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/69734940e99d0d3a.
Report an issue: GitHub.