{"record":{"id":"10d981b2a72aee94","repo":"paperclipai/paperclip","slug":"task-watchdog-review-is-stale-because-the-watched","errorCode":null,"errorMessage":"Task-watchdog review is stale because the watched subtree stop fingerprint changed; refresh the source state before mutating it.","messagePattern":"Task-watchdog review is stale because the watched subtree stop fingerprint changed; refresh the source state before mutating it\\.","errorType":"http","errorClass":null,"httpStatus":409,"severity":"error","filePath":"server/src/routes/issues.ts","lineNumber":4302,"sourceCode":"      action: \"tasks:manage_active_checkouts\",\n      resource: { type: \"issue\", companyId, assigneeAgentId },\n    });\n    return decision.allowed;\n  }\n\n  async function assertAgentIssueMutationAllowed(\n    req: Request,\n    res: Response,\n    issue: {\n      id: string;\n      companyId: string;\n      projectId: string | null;\n      parentId: string | null;\n      status: string;\n      assigneeAgentId: string | null;\n      assigneeUserId: string | null;\n      reviewPolicy?: IssueReviewPolicy | null;\n      /** Used only to name the task in denial copy (plan §6). */\n      identifier?: string | null;\n    },\n    options: { allowVisibleIssueWrite?: boolean } = {},\n  ) {\n    if (req.actor.type !== \"agent\") return true;\n    const actorAgentId = req.actor.agentId;\n    if (!actorAgentId) {\n      res.status(403).json({ error: \"Agent authentication required\" });\n      return false;\n    }\n    // Task-watchdog runs receive a scoped *grant* to mutate issues inside the\n    // watched subtree. This must be evaluated before the base assignee-ownership\n    // boundary below: that boundary denies an agent mutating an issue owned by a\n    // different agent, which is exactly the watchdog's primary job\n    // (SPEC-implementation §9.9 — comment, transition, reassign within the\n    // watched subtree). The watchdog scope can only widen access to the watched\n    // subtree; downstream status-transition, assignment, recovery, and budget\n    // guards in the route handlers still apply.","sourceCodeStart":4284,"sourceCodeEnd":4320,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/routes/issues.ts#L4284-L4320","documentation":"assertFreshTaskWatchdogSourceMutation revalidated the watchdog scope and the watched subtree's stop fingerprint changed since the run started, so the watchdog's view of the source state is stale and mutations are refused until the run refreshes state.","triggerScenarios":"Thrown at server/src/routes/issues.ts:4138 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Wait for the conflicting state to clear (running job, hold, pause, or stale fingerprint), refresh the current state, then retry the operation."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}