aaif-goose/goose · error
Message with id ${messageId} not found in current messages
Error message
Message with id ${messageId} not found in current messages What it means
Thrown by the message-edit path in chatSessionController when the message id submitted for edit is not present in the current UI snapshot's messages array. The controller re-reads the live snapshot at submit time (options.getCurrentSnapshot()), so the id the caller captured earlier (e.g. from a rendered list) can be stale. It also falls back to nothing — there is no storedSnapshot lookup for the message itself.
Source
Thrown at ui/desktop/src/acp/chatSessionController.ts:258
async function updateMessage(
sessionId: string,
messageId: string,
newContent: string,
editType: 'fork' | 'edit',
retainedImages: ImageData[],
options: AcpSubmitMessageOptions
): Promise<void> {
assertNoPendingPromptCancellation(sessionId);
const currentSnapshot = options.getCurrentSnapshot();
const storedSnapshot = acpChatSessionStore.getSnapshot(sessionId);
const activePromptAttemptId = storedSnapshot?.activePromptAttemptId;
const currentMessages = currentSnapshot?.messages ?? [];
const message = currentMessages.find((m) => m.id === messageId);
if (!message) {
throw new Error(`Message with id ${messageId} not found in current messages`);
}
if (editType === 'fork') {
await forkSessionWithEditedMessage(sessionId, message, newContent, retainedImages);
return;
}
const editSnapshot = currentSnapshot ?? storedSnapshot;
const isPendingToolPermission =
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) {View on GitHub (pinned to 3810898a74)
Solutions
- Pass the message id from the same snapshot you got it from, re-read immediately before calling submit.
- Ensure the edit UI is disabled for messages that no longer exist (derive the editable list from the live snapshot).
- Verify the sessionId matches the snapshot store entry — a mismatched session yields an empty currentMessages array.
- Treat this error as a no-op UX signal (message gone) rather than a hard failure where appropriate.
Example fix
// before
const message = currentMessages.find((m) => m.id === messageId);
if (!message) {
throw new Error(`Message with id ${messageId} not found in current messages`);
}
// after (caller refreshes state and degrades gracefully)
const snapshot = options.getCurrentSnapshot();
const message = (snapshot?.messages ?? []).find((m) => m.id === messageId);
if (!message) {
console.warn(`Message ${messageId} no longer present; ignoring edit`);
return; // or re-render from the fresh snapshot and re-prompt the user
} Defensive patterns
Strategy: validation
Validate before calling
// Verify the message is still present in the live snapshot before submitting an edit
function canEditMessage(snapshot: { messages: { id: string }[] } | undefined, messageId: string): boolean {
return Boolean(snapshot?.messages.some((m) => m.id === messageId));
}
if (!canEditMessage(options.getCurrentSnapshot(), messageId)) {
return; // message already gone; nothing to edit
} Type guard
function findEditableMessage(
messages: { id: string }[],
messageId: string
): { id: string } | undefined {
return messages.find((m) => m.id === messageId);
} Try / catch
try {
await submitEditedMessage(sessionId, messageId, newContent, retainedImages, options);
} catch (error) {
if (/not found in current messages/.test(String(error))) {
// Stale UI: refresh from the store and drop the edit silently
refreshFromSnapshot(sessionId);
return;
}
throw error;
} Prevention
- Derive edit affordances from the same live snapshot used at submit time.
- Invalidate cached message ids whenever the session id or snapshot identity changes.
- Disable edit UI during session reset/clear transitions.
When it happens
Trigger: Submitting an edit for a message that was removed because the session was reset, cleared, or switched between render and submit; using a message id from a previous session id; a fork/branch operation replaced the message list; concurrent edit where another action already truncated the conversation.
Common situations: User opens the edit dialog, then the agent finishes and UI reconciles messages, then submits; message ids persisted in component state across a session switch; tests calling the edit API with fabricated ids.
Related errors
- Cannot update message while prompt is active
- 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/a3b91adb38cd1cd4.
Report an issue: GitHub.