paperclipai/paperclip · error

Only queued comments can be canceled

Error message

Only queued comments can be canceled

What it means

409 on comment cancel. Fires when a cancel is requested for an owned comment but there is no active run on the issue — cancel semantics only exist while a run is active and the comment is queued against it.

Source

Thrown at server/src/routes/issues.ts:12588

  router.post("/issues/:id/interactions", validate(createIssueThreadInteractionSchema), async (req, res) => {
    const id = req.params.id as string;
    const issue = await getAccessibleResource(req, res, svc.getById(id), "Issue not found");
    if (!issue) return;
    if (req.actor.type === "agent") {
      if (!(await assertAgentIssueMutationAllowed(req, res, issue, { allowVisibleIssueWrite: true }))) return;
      if (await assertLowTrustControlPlaneDenied(req, res, issue.companyId, issue)) return;
    } else {
      assertBoard(req);
    }

    const actor = getActorInfo(req);
    const agentSourceRunId = req.actor.type === "agent" ? requireAgentRunId(req, res) : null;
    if (req.actor.type === "agent" && !agentSourceRunId) return;
    if (
      req.body.kind === "request_confirmation"
      && req.body.addresseeAgentId
      && req.body.payload?.toolAction !== undefined
    ) {
      throw badRequest("Tool-action confirmations cannot be addressed to agents");
    }
    if (req.body.kind === "request_confirmation" && req.body.payload?.toolAction !== undefined) {
      throw unprocessable("payload.toolAction is server-owned metadata and cannot be supplied when creating an interaction");
    }
    if (req.body.kind === "request_confirmation" && req.body.payload?.secretProposal !== undefined) {
      throw unprocessable("payload.secretProposal is server-owned metadata and cannot be supplied when creating an interaction");
    }

    // Plan-document confirmation targets are validated authoritatively inside
    // issueThreadInteractionService.create, which re-reads the plan document's
    // latest revision and rejects a stale/missing target under the same insert
    // transaction (see assertRequestConfirmationTargetIsCurrent). We deliberately
    // do not pre-check the revision here: a separate route-level read would be
    // non-atomic with the insert and only duplicate the service gate.
    const interaction = await issueThreadInteractionService(db).create(issue, {
      ...req.body,

View on GitHub (pinned to 01ad858492)

Solutions

  1. This is an authorization rule, not a bug: perform the action with an actor that satisfies the stated constraint (board user, the owning agent, or an in-scope resource).
  2. If access should be allowed, verify the actor's credentials/company scope and the resource's ownership before retrying.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/routes/issues.ts:11584 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18). Data as JSON: /api/errors/0d7961323b08ff2a. Report an issue: GitHub.