{"record":{"id":"e1afe74e7c0473ab","repo":"mastra-ai/mastra","slug":"a-resource-id-is-required-when-using-memory-provi","errorCode":null,"errorMessage":"A resource ID is required when using memory. Provide memory.resource in the request body, or configure server auth with mapUserToResourceId to derive it from the authenticated user.","messagePattern":"A resource ID is required when using memory\\. Provide memory\\.resource in the request body, or configure server auth with mapUserToResourceId to derive it from the authenticated user\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"packages/server/src/server/handlers/utils.ts","lineNumber":92,"sourceCode":"  requestContext: RequestContext | undefined,\n  clientResourceId: string | undefined,\n): string | undefined {\n  const contextResourceId = requestContext?.get(MASTRA_RESOURCE_ID_KEY) as string | undefined;\n  return contextResourceId || clientResourceId;\n}\n\n/**\n * Ensures a memory request has a resolvable resource ID. The body's\n * `memory.resource` is optional so authenticated setups can rely on the\n * server-derived resource ID (MASTRA_RESOURCE_ID_KEY set via mapUserToResourceId).\n * When neither the body nor the request context provides one, reject with a\n * clear 400 instead of failing deep inside agent execution.\n */\nexport function requireEffectiveResourceId(\n  effectiveResourceId: string | undefined,\n): asserts effectiveResourceId is string {\n  if (!effectiveResourceId) {\n    throw new HTTPException(400, {\n      message:\n        'A resource ID is required when using memory. Provide memory.resource in the request body, or configure server auth with mapUserToResourceId to derive it from the authenticated user.',\n    });\n  }\n}\n\n/**\n * Gets the effective threadId, preferring the reserved key from requestContext\n * over client-provided values for security.\n */\nexport function getEffectiveThreadId(\n  requestContext: RequestContext | undefined,\n  clientThreadId: string | undefined,\n): string | undefined {\n  const contextThreadId = requestContext?.get(MASTRA_THREAD_ID_KEY) as string | undefined;\n  return contextThreadId || clientThreadId;\n}\n","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/utils.ts#L74-L110","documentation":"When memory is enabled, agent interactions must be scoped to a resource ID (the user/owner of threads). requireEffectiveResourceId throws this 400 when no effective resource ID could be resolved — neither from the request body's memory.resource nor from server auth via a mapUserToResourceId hook. This prevents threads from being created or read without an owner.","triggerScenarios":"Calling generate/stream routes on an agent with memory enabled, where the body has no memory.resource and the server was not configured with authentication providing mapUserToResourceId; also resume/stream-until-idle routes hitting the same check.","commonSituations":"Local/dev setups with auth disabled (so no user to map) while the agent uses memory; forgetting to pass memory: { resource: 'user-123' } in the request body; a recent server version tightening the old implicit resourceId fallback into this explicit 400.","solutions":["Pass memory: { resource: '<resourceId>' } in the request body for memory-enabled agents.","Configure server authentication and implement mapUserToResourceId so the resource ID is derived from the authenticated user.","If the request should be memoryless, target an agent without memory or omit memory-related options per the current API.","After upgrading, update clients that relied on implicit resourceId defaults."],"exampleFix":"// before\nawait fetch('/api/agents/assistant/stream', { method: 'POST', body: JSON.stringify({ messages }) });\n// after\nawait fetch('/api/agents/assistant/stream', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ messages, memory: { resource: 'user-123' } }),\n});","handlingStrategy":"validation","validationCode":"function validateMemoryResource(body: { memory?: { resource?: string } }, hasServerAuth: boolean): asserts body is { memory: { resource: string } } {\n  const resource = body?.memory?.resource;\n  if (!resource && !hasServerAuth) {\n    throw new Error('memory.resource is required in the body when the agent uses memory and no mapUserToResourceId is configured');\n  }\n}","typeGuard":"function hasEffectiveResource(body: unknown): body is { memory: { resource: string } } {\n  const b = body as any;\n  return !!b && typeof b.memory?.resource === 'string' && b.memory.resource.length > 0;\n}","tryCatchPattern":"try {\n  const res = await fetch('/api/agents/assistant/stream', { method: 'POST', body: JSON.stringify(payload) });\n  if (res.status === 400 && (await res.text()).includes('resource ID is required')) {\n    throw new Error('Add memory.resource to the body or configure mapUserToResourceId on the server');\n  }\n  return res.body;\n} catch (e) { throw e; }","preventionTips":["Always pass memory: { resource } for memory-enabled agents.","Configure mapUserToResourceId when server auth is enabled.","Document the resourceId requirement for all API consumers.","After server upgrades, re-check memory API changes (implicit fallbacks were removed)."],"tags":["http-400","memory","resource-id","authentication"],"backgroundTag":"missing-resource-id","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}