paperclipai/paperclip · error · QueuedCommentMutationError
queued_comment_not_pending
queued_comment_not_pending
Error message
The queued message is no longer pending
What it means
QueuedCommentMutationError with code queued_comment_not_pending, thrown from createEditQueuedComment when the commentId supplied to editQueuedComment cannot be found among the locked queue's pending entries. The queue was locked and the revision matched, but the target comment is no longer part of the pending queue.
Solutions
- Re-fetch the queue and confirm the commentId still appears in the pending entries before retrying
- Remove the edit affordance for comments no longer pending and refresh the queue view
- Verify the commentId and queueId belong to the same issue/queue
- If this recurs, check for multiple sessions mutating the same queue and serialize edits through one view
Example fix
// before
await editQueuedComment({ issue, actor, queueId, revision, commentId: staleId, body });
// after
const queue = await getQueuedComments({ issue, actor });
if (!queue.entries.some((e) => e.comment.id === commentId)) {
throw new Error('comment no longer pending; refresh queue');
}
await editQueuedComment({ issue, actor, queueId, revision: queue.revision, commentId, body }); Defensive patterns
Strategy: validation
Validate before calling
const queue = await getQueuedComments({ issue, actor });
const entry = queue.entries.find((e) => e.comment.id === commentId);
if (!entry) throw new Error('comment is no longer pending; refresh the queue'); Type guard
function isPendingEntry(queue: { entries: { comment: { id: string } }[] }, commentId: string): boolean {
return queue.entries.some((e) => e.comment.id === commentId);
} Try / catch
try {
await editQueuedComment(input);
} catch (e) {
if (e?.code === 'queued_comment_not_pending') {
await refreshQueue(); // entry gone: show current state
return;
}
throw e;
} Prevention
- Validate the commentId exists in a freshly fetched queue before editing
- Refresh the queue view whenever another session may have mutated it
- Never reuse commentIds across queue revisions
- Check commentId and queueId refer to the same issue
When it happens
Trigger: Editing a commentId that was already dispatched, discarded, or removed between the client's snapshot and the locked queue read; passing a commentId belonging to a different queue or issue; a typo'd or deleted comment id.
Common situations: Stale UI listing a message that was discarded in another tab; client retrying an edit after the message was flushed by the wake scheduler; mixing up comment ids across queue revisions.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- codex_run_attach_busy
- goal_not_found
- opencode_run_attach_busy
- Photon state changed concurrently; retry
- queued_comment_already_dispatching
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/eeac6764a108e06d.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/modules/wake-queue/application/queued-comment-use-cases.ts:91
revision: string;
body: string;
now: Date;
};
export type EditQueuedCommentResult = {
queue: QueuedCommentQueueSnapshot;
activityPublication: QueuedCommentActivityPublication;
};
export function createEditQueuedComment(deps: { issueLock: QueuedCommentIssueLockWriter }) {
return async function editQueuedComment(input: EditQueuedCommentInput): Promise<EditQueuedCommentResult> {
return deps.issueLock.withLockedQueue(
{ issue: input.issue, actor: input.actor, queueId: input.queueId },
async (locked, tx) => {
requireMutationTarget(locked.queue, input.queueId, input.revision);
const entry = locked.queue.entries.find((candidate) => candidate.comment.id === input.commentId);
if (!entry) {
throw new QueuedCommentMutationError("queued_comment_not_pending", "The queued message is no longer pending");
}
if (!entry.canEdit) {
throw new QueuedCommentMutationForbiddenError("Only the queued message author can edit it");
}
const updated = await tx.updateCommentBody({
issueId: input.issue.id,
commentId: input.commentId,
body: input.body,
updatedAt: input.now,
});
if (!updated) {
throw new QueuedCommentMutationError("queued_comment_not_pending", "The queued message is no longer pending");
}
await tx.touchIssueUpdatedAt({ issueId: input.issue.id, updatedAt: input.now });
await tx.syncCommentReferences(input.commentId);
await tx.syncCommentExternalObjectsSafely(input.commentId);
View on GitHub (pinned to 3f1d897a7c)