{"record":{"id":"2af10a58f1ec56f0","repo":"mastra-ai/mastra","slug":"bound-factory-work-item-not-found","errorCode":null,"errorMessage":"Bound Factory work item not found.","messagePattern":"Bound Factory work item not found\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/rules/tools.ts","lineNumber":86,"sourceCode":"          sessions: options.sessions,\n        });\n        const currentAddress = currentResolution?.address ?? null;\n        const toolCallId = execution.agent?.toolCallId;\n        if (!currentAddress || !toolCallId) {\n          throw new Error('Factory transitions require an authenticated bound agent tool call.');\n        }\n        const binding = await options.storage.findActiveRunBinding(currentAddress);\n        // Authority is the work item this session is bound to, not the individual\n        // binding row. Handing the next role its turn in an existing session\n        // rotates the binding, and tools built for the previous role stay live\n        // across that rotation; keying on row identity would strand the run that\n        // the rotation exists to start. Re-pointing a session at a different item\n        // is the hijack this guards against.\n        if (!binding || binding.workItemId !== availableBinding.workItemId) {\n          throw new Error('Factory agent binding is unavailable, revoked, or no longer matches this session.');\n        }\n        const item = await options.storage.get({ orgId: binding.orgId, id: binding.workItemId });\n        if (!item) throw new Error('Bound Factory work item not found.');\n        const triageType =\n          'triageType' in input && isFactoryTriageType(input.triageType) ? input.triageType : undefined;\n\n        const result = await options.transitionService.transition({\n          orgId: binding.orgId,\n          factoryProjectId: binding.factoryProjectId,\n          workItemId: binding.workItemId,\n          board: boardForSource(item.externalSource?.type),\n          stage,\n          expectedRevision,\n          actor: { type: 'agent', bindingId: binding.id, role: binding.role },\n          ingress: { type: 'agent', identity: `${binding.id}:${toolCallId}` },\n          cause: rationale,\n          ...(triageType ? { triageType } : {}),\n        });\n\n        // A phase EXIT is the natural moment to ask what was worth keeping:\n        // run the subconscious curator directly on the session's thread.","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/rules/tools.ts#L68-L104","documentation":"Once the session's binding is validated, the tool loads the bound work item via `storage.get({orgId, id: binding.workItemId})` and throws if it no longer exists. The binding references an item that was deleted (or is not visible in this org), so no transition can be performed. This is a referential-integrity failure between the run binding and the work-items store.","triggerScenarios":"`options.storage.get` for the binding's orgId and workItemId returns null/undefined at tool execution time — the work item was deleted, purged, hard-migrated to another org, or the storage domain is pointed at a different dataset than the one the binding was written to.","commonSituations":"A maintainer or automation deleted/closed-and-purged the issue/PR-backed item while the agent run was in flight; environment mismatch (dev binding row pointing at prod items); storage backend swapped or re-seeded without cleaning run bindings.","solutions":["Verify the work item exists via storage.get with the binding's exact orgId and id; recreate it if it was deleted and the run is still wanted.","Delete or expire the stale run binding and restart the run so binding and item are recreated together.","Confirm both the bindings and work-items domains use the same storage instance/database and orgId; fix config if they diverge.","Check for deletion automation (linear/github sync, cleanup jobs) racing the agent run and disable or rescope it."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const item = await storage.get({ orgId: binding.orgId, id: binding.workItemId });\nif (!item) throw new Error('Bound work item missing; refresh binding or recreate item before transitioning.');","typeGuard":"function workItemExists(\n  item: { id: string; orgId: string } | null | undefined,\n): item is { id: string; orgId: string } {\n  return item != null && typeof item.id === 'string' && typeof item.orgId === 'string';\n}","tryCatchPattern":"try {\n  await transitionTool.execute(input, execution);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Bound Factory work item not found.') {\n    // mark binding stale, skip the transition, alert maintainers\n  } else throw e;\n}","preventionTips":["Verify the bound item exists right before starting a run and expire bindings pointing at missing items.","Use the same storage instance/config for bindings and work items; never mix dev and prod datasets.","Coordinate item-deletion automation with factory runs, or resolve bindings instead of hard-deleting items.","Alert on storage.get misses for bound workItemIds to catch referential drift early."],"tags":["factory","storage","data-integrity","work-item"],"backgroundTag":"referenced-record-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}