mastra-ai/mastra · warning · HTTPException

Not found

Error message

Not found

What it means

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.

Source

Thrown at packages/server/src/server/handlers/authorship.ts:222

  const owner = record.authorId ?? null;

  if (owner === null) return;
  if (record.visibility === 'public') return;
  if (hasAdminBypass(requestContext, resource)) return;

  const callerAuthorId = getCallerAuthorId(requestContext);
  // No authenticated user on the request context means auth is not configured
  // (single-user/dev mode). When auth IS configured, coreAuthMiddleware
  // rejects unauthenticated requests with 401 before they reach handlers,
  // so an absent user here genuinely means no auth provider.
  if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;
  if (callerAuthorId === owner) return;

  if (hasScopedPermission({ requestContext, resource, action: 'read', resourceId })) {
    return;
  }

  throw new HTTPException(404, { message: 'Not found' });
}

/**
 * Asserts the caller has execute access to the record. Throws 404 if not.
 *
 * Execute access is granted when:
 * - The record has no owner (legacy/public), OR
 * - The record is marked `visibility: 'public'`, OR
 * - The caller owns the record, OR
 * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR
 * - The caller holds `<resource>:execute` / `<resource>:execute:<resourceId>`, OR
 * - The caller holds `<resource>:read` / `<resource>:read:<resourceId>`
 *   (read implies the ability to consume/chat with the resource).
 */
export function assertExecuteAccess(args: {
  requestContext: RequestContext;
  resource: string;
  resourceId?: string;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Verify the record ID exists and is visible to you — 404 deliberately conflates 'missing' and 'forbidden', so check authorship first.
  2. Obtain the record from its author or have an admin grant you a scoped read permission for that resource/ID.
  3. Confirm your auth middleware populates requestContext so hasScopedPermission sees your grants.
  4. If you are the author, ensure the request is authenticated as the same identity (same author ID) that created the record.

Example fix

// before: assuming 403 for forbidden
if (!res.ok) throw new Error('Forbidden');

// after: treat 404 as 'missing or no access', verify ID/grants
if (res.status === 404) {
  const exists = await adminCheck(id);
  throw new Error(exists ? 'No read access to this record' : 'Record does not exist');
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Client-side pre-check: only request records you authored or know are shared with you
if (!recordIdsKnownVisible.has(id)) {
  throw new Error(`Skipping ${id}: not authored by you and not confirmed readable`);
}

Try / catch

try {
  const agent = await getStoredAgent(id);
} catch (e) {
  if (e.status === 404) {
    // 404 conflates 'missing' and 'no read access' by design
    throw new Error(`Stored agent ${id} does not exist or you lack read access.`);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/43c60e7a63a01ba0. Report an issue: GitHub.