{"record":{"id":"43c60e7a63a01ba0","repo":"mastra-ai/mastra","slug":"not-found","errorCode":null,"errorMessage":"Not found","messagePattern":"Not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"warning","filePath":"packages/server/src/server/handlers/authorship.ts","lineNumber":222,"sourceCode":"  const owner = record.authorId ?? null;\n\n  if (owner === null) return;\n  if (record.visibility === 'public') return;\n  if (hasAdminBypass(requestContext, resource)) return;\n\n  const callerAuthorId = getCallerAuthorId(requestContext);\n  // No authenticated user on the request context means auth is not configured\n  // (single-user/dev mode). When auth IS configured, coreAuthMiddleware\n  // rejects unauthenticated requests with 401 before they reach handlers,\n  // so an absent user here genuinely means no auth provider.\n  if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n  if (callerAuthorId === owner) return;\n\n  if (hasScopedPermission({ requestContext, resource, action: 'read', resourceId })) {\n    return;\n  }\n\n  throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has execute access to the record. Throws 404 if not.\n *\n * Execute access is granted when:\n * - The record has no owner (legacy/public), OR\n * - The record is marked `visibility: 'public'`, OR\n * - The caller owns the record, OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:execute` / `<resource>:execute:<resourceId>`, OR\n * - The caller holds `<resource>:read` / `<resource>:read:<resourceId>`\n *   (read implies the ability to consume/chat with the resource).\n */\nexport function assertExecuteAccess(args: {\n  requestContext: RequestContext;\n  resource: string;\n  resourceId?: string;","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/authorship.ts#L204-L240","documentation":"assertReadAccess throws this 404 when the caller is neither the record's author nor holds a scoped 'read' permission for the resource. A 404 (rather than 403) is intentional: it hides the existence of stored agents/skills from unauthorized callers. It is raised by the favorite/unfavorite/export/get/dependents stored-agent routes and favorite stored-skill route.","triggerScenarios":"GET /stored-agents/:id (or its dependents/export) or POST/DELETE favorite routes where: the record doesn't exist (lookup failed upstream), the caller is not the author, and the caller's requestContext lacks a scoped read permission for that resource.","commonSituations":"Sharing an agent/skill ID with a teammate who has no read grant; accessing a private record via API with a token lacking read scope; referencing a deleted or never-existing ID; cross-tenant access where the record belongs to another author.","solutions":["Verify the record ID exists and is visible to you — 404 deliberately conflates 'missing' and 'forbidden', so check authorship first.","Obtain the record from its author or have an admin grant you a scoped read permission for that resource/ID.","Confirm your auth middleware populates requestContext so hasScopedPermission sees your grants.","If you are the author, ensure the request is authenticated as the same identity (same author ID) that created the record."],"exampleFix":"// before: assuming 403 for forbidden\nif (!res.ok) throw new Error('Forbidden');\n\n// after: treat 404 as 'missing or no access', verify ID/grants\nif (res.status === 404) {\n  const exists = await adminCheck(id);\n  throw new Error(exists ? 'No read access to this record' : 'Record does not exist');\n}","handlingStrategy":"try-catch","validationCode":"// Client-side pre-check: only request records you authored or know are shared with you\nif (!recordIdsKnownVisible.has(id)) {\n  throw new Error(`Skipping ${id}: not authored by you and not confirmed readable`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const agent = await getStoredAgent(id);\n} catch (e) {\n  if (e.status === 404) {\n    // 404 conflates 'missing' and 'no read access' by design\n    throw new Error(`Stored agent ${id} does not exist or you lack read access.`);\n  }\n  throw e;\n}","preventionTips":["Treat 404 as 'missing OR forbidden' — don't probe IDs to discover existence.","Share records by adjusting audience/visibility rather than passing raw IDs.","Ensure auth middleware populates requestContext so scoped read permissions are honored.","Verify IDs against a list endpoint you're permitted to call before fetching directly."],"tags":["authorization","http-404","rbac"],"backgroundTag":"resource-not-found-or-forbidden","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}