{"record":{"id":"898661ac85e260c9","repo":"mastra-ai/mastra","slug":"subconscious-requires-threadid-to-derive-scoped-kn","errorCode":null,"errorMessage":"Subconscious requires threadId to derive scoped knowledge.","messagePattern":"Subconscious requires threadId to derive scoped knowledge\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/memory/src/processors/observational-memory/subconscious/capture.ts","lineNumber":87,"sourceCode":"const CAPTURE_REASON_INSTRUCTIONS = `Every record requires a reason: the concrete why behind capturing it, in one short sentence - what it cost to learn or when it will matter again (and for pinned records, why it must stay in context). Never write generic filler such as \"seemed relevant\" or \"useful context\".`;\n\nfunction clampScope(level: KnowledgeScopeLevel, ceiling?: KnowledgeScopeLevel): KnowledgeScopeLevel {\n  return ceiling && SCOPE_ORDER[level] < SCOPE_ORDER[ceiling] ? ceiling : level;\n}\n\nfunction requireScopeContext(context: ExtractorRuntimeContext): KnowledgeScope {\n  const organizationId = context.requestContext?.get('organizationId');\n  if (typeof organizationId !== 'string' || !organizationId.trim()) {\n    throw new Error(\n      'Subconscious requires requestContext.organizationId to derive scoped knowledge. Set organizationId on the request context for this conversation.',\n    );\n  }\n  const resourceId = resolveKnowledgeResourceId(context.requestContext, context.resourceId);\n  if (!resourceId) {\n    throw new Error('Subconscious requires resourceId to derive scoped knowledge.');\n  }\n  if (!context.threadId) {\n    throw new Error('Subconscious requires threadId to derive scoped knowledge.');\n  }\n  return [`org:${organizationId}`, `resource:${resourceId}`, `thread:${context.threadId}`];\n}\n\nasync function getKnowledgeStore(context: ExtractorRuntimeContext): Promise<KnowledgeStorage> {\n  if (!context.memory) throw new Error('Subconscious capture requires an active Memory instance.');\n  const store = await context.memory.storage.getStore('knowledge');\n  if (!store) {\n    throw new Error(\n      'Subconscious requires a knowledge storage domain. Configure a storage adapter that provides stores.knowledge.',\n    );\n  }\n  return store;\n}\n\nfunction parseWhen(value: string | undefined): Date | undefined {\n  if (!value) return undefined;\n  const when = new Date(value);","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/processors/observational-memory/subconscious/capture.ts#L69-L105","documentation":"Knowledge scopes include the conversation thread; requireScopeContext throws when context.threadId is falsy, since knowledge captured without a thread can't be scoped/attributed to a conversation.","triggerScenarios":"Subconscious capture runs with organizationId and resourceId present but threadId missing — e.g. invoking memory processors outside a thread-backed conversation.","commonSituations":"Background/batch jobs invoking capture without creating a thread; custom pipelines calling processors directly; thread creation skipped before the first generate.","solutions":["Ensure a thread exists and its id is passed to the memory call ({ threadId })","Create a thread first (memory.createThread) for background jobs that need capture","Guard processor wiring so capture only runs in thread-scoped conversations"],"exampleFix":"// before\nawait memory.capture({ organizationId, resourceId });\n// after\nconst thread = await memory.createThread({ resourceId: 'user_42' });\nawait memory.capture({ organizationId, resourceId: 'user_42', threadId: thread.id });","handlingStrategy":"validation","validationCode":"if (!threadId) throw new Error('threadId required for Subconscious capture');","typeGuard":"const hasThread = (p: { threadId?: string }) => typeof p.threadId === 'string' && p.threadId.length > 0;","tryCatchPattern":"try { await memory.capture(params) } catch (e) { if (String(e).includes('threadId')) { await ensureThreadThenRetry(); } else throw e; }","preventionTips":["Create threads before any conversation that uses Subconscious","Never invoke memory processors outside thread-scoped flows","Include threadId in job payloads for background processing"],"tags":["configuration","subconscious","thread","request-context"],"backgroundTag":"missing-request-context","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}