{"record":{"id":"f89b3fb2a627726b","repo":"paperclipai/paperclip","slug":"cheap-status-only-recovery-runs-cannot-assign-down","errorCode":null,"errorMessage":"Cheap status-only recovery runs cannot assign downstream issue work to the cheap model profile","messagePattern":"Cheap status-only recovery runs cannot assign downstream issue work to the cheap model profile","errorType":"http","errorClass":null,"httpStatus":403,"severity":"error","filePath":"server/src/routes/issues.ts","lineNumber":5077,"sourceCode":"      return false;\n    }\n    const scope = await resolveTaskWatchdogMutationScope(db, req.actor);\n    if (scope.kind === \"none\") {\n      res.status(403).json({ error: \"Only task-watchdog runs can create watchdog-discovered product bug follow-ups\" });\n      return false;\n    }\n    if (scope.kind === \"invalid\") {\n      res.status(403).json({\n        error: scope.detail,\n        details: {\n          securityPrinciples: [\"Least Privilege\", \"Complete Mediation\", \"Fail Securely\"],\n        },\n      });\n      return false;\n    }\n    if (scope.companyId !== companyId) {\n      res.status(403).json({ error: \"Task-watchdog product bug follow-up target is outside the watchdog company\" });\n      return false;\n    }\n\n    const sourceIssue = await svc.getById(scope.watchedIssueId);\n    if (!sourceIssue || sourceIssue.companyId !== companyId) {\n      res.status(404).json({ error: \"Watched source issue not found\" });\n      return false;\n    }\n    const watchdogIssue = scope.watchdogIssueId ? await svc.getById(scope.watchdogIssueId) : null;\n    if (watchdogIssue && watchdogIssue.companyId !== companyId) {\n      res.status(403).json({ error: \"Task-watchdog product bug evidence issue is outside the watchdog company\" });\n      return false;\n    }\n\n    return { scope, discovery, sourceIssue, watchdogIssue };\n  }\n\n  function isStatusOnlyRecoveryContext(contextSnapshot: unknown) {\n    if (!contextSnapshot || typeof contextSnapshot !== \"object\" || Array.isArray(contextSnapshot)) return false;","sourceCodeStart":5059,"sourceCodeEnd":5095,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/routes/issues.ts#L5059-L5095","documentation":"The request asks for the cheap model profile on issue assignment, but the acting run is a cheap status-only recovery run; such runs are limited to status updates and may not steer downstream work to the cheap profile.","triggerScenarios":"Thrown at server/src/routes/issues.ts:4913 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["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).","If access should be allowed, verify the actor's credentials/company scope and the resource's ownership before retrying."],"exampleFix":null,"handlingStrategy":"validation","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"}