{"record":{"id":"983d86b26dce907c","repo":"mastra-ai/mastra","slug":"stored-resource-scope-is-required","errorCode":null,"errorMessage":"Stored resource scope is required","messagePattern":"Stored resource scope is required","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"packages/server/src/server/utils.ts","lineNumber":85,"sourceCode":"  requestContext: RequestContext | undefined,\n): Promise<StoredResourceScope | undefined> {\n  const scopeConfig = mastra?.getServer?.()?.storedResources?.scope;\n  if (!scopeConfig) {\n    return undefined;\n  }\n\n  const options = scopeConfig === true ? {} : scopeConfig;\n  const metadataKey = options.metadataKey ?? DEFAULT_STORED_RESOURCE_SCOPE_METADATA_KEY;\n  const user = requestContext?.get('user');\n  const resolved = options.resolve\n    ? await options.resolve({ requestContext, user })\n    : (requestContext?.get(MASTRA_RESOURCE_ID_KEY) as string | undefined);\n\n  if (!resolved) {\n    if (options.requireScope === false) {\n      return undefined;\n    }\n    throw new HTTPException(403, { message: 'Stored resource scope is required' });\n  }\n\n  return { metadataKey, value: resolved };\n}\n\nexport function scopeStoredResourceMetadata(\n  metadata: Record<string, unknown> | undefined,\n  scope: StoredResourceScope | undefined,\n): Record<string, unknown> | undefined {\n  if (!scope) {\n    return metadata;\n  }\n\n  return {\n    ...(metadata ?? {}),\n    [scope.metadataKey]: scope.value,\n  };\n}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/utils.ts#L67-L103","documentation":"Agent-version stored-resource routes require that the resource scope (a resource id used as a metadata scoping key) be resolvable from the request. getStoredResourceScope throws HTTP 403 when no scope can be resolved from the request context or headers and the caller did not opt out via options.requireScope === false. This prevents leaking or mutating stored resources across resource boundaries.","triggerScenarios":"Hitting any agent-version route (LIST/CREATE/GET/ACTIVATE/RESTORE/DELETE_AGENT_VERSIONS) without providing a resource id (e.g. the x-mastra-resource-id header) and without requestContext containing MASTRA_RESOURCE_ID_KEY.","commonSituations":"Calling agent-version REST endpoints with curl/scripts that omit the resource-id header; server middleware not propagating the resource id into requestContext; misconfigured auth that no longer sets MASTRA_RESOURCE_ID_KEY after an upgrade.","solutions":["Send the resource id header (x-mastra-resource-id) with the request","Ensure your auth/context middleware sets the MASTRA_RESOURCE_ID_KEY in requestContext for these routes","If the deployment intentionally has no resource scoping, configure the route/context with requireScope: false"],"exampleFix":"// before\ncurl http://localhost:4111/api/agents/myAgent/versions\n// after\ncurl -H 'x-mastra-resource-id: tenant-1' http://localhost:4111/api/agents/myAgent/versions","handlingStrategy":"validation","validationCode":"if (!process.env.DEFAULT_RESOURCE_ID && !requestHeaders['x-mastra-resource-id']) {\n  throw new Error('Resource id must be provided for agent-version APIs');\n}","typeGuard":"const hasScope = (ctx: { get(k: string): unknown }): boolean =>\n  typeof ctx.get('MASTRA_RESOURCE_ID_KEY') === 'string';","tryCatchPattern":null,"preventionTips":["Centralize agent-version calls in a client that always attaches the scope header","Add integration tests that call version routes without the header to catch regressions","Keep MASTRA_RESOURCE_ID_KEY propagation in one middleware"],"tags":["http-403","resource-scope","agent-versions"],"backgroundTag":"missing-resource-scope","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}