mastra-ai/mastra · error · HTTPException

Not found

Error message

Not found

What it means

The channels routes return HTTP 404 'Not found' when the request context has no authenticated identity (no caller author ID and no Mastra user), no admin bypass for 'channels', and no scoped 'channels:write' permission. It deliberately mirrors the no-auth-configured pass-through of assertWriteAccess: if the deployment has no auth configured at all, the check is skipped. This is an authorization failure disguised as a 404 to avoid leaking channel/agent existence to unauthorized callers.

Source

Thrown at packages/server/src/server/handlers/channels.ts:96

    // Code-defined agents have no owner/ACL — route's requiresAuth /
    // requiresPermission is the gate. Pass-through.
    return;
  }

  if (action === 'connect') {
    throw new HTTPException(404, { message: `Agent "${agentId}" not found` });
  }

  // Disconnect against an unknown agentId = orphan cleanup (stored agent was
  // deleted but the channel installation row is still around). Allow it, but
  // gate on channels:write so this isn't an "any authenticated user" backdoor.
  // Follow the same no-auth-configured pass-through as assertWriteAccess.
  const callerAuthorId = getCallerAuthorId(requestContext);
  if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;
  if (hasAdminBypass(requestContext, 'channels')) return;
  if (hasScopedPermission({ requestContext, resource: 'channels', action: 'write' })) return;

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

// ============================================================================
// Route Definitions
// ============================================================================

/**
 * GET /channels/platforms - List available channel platforms
 */
export const LIST_CHANNEL_PLATFORMS_ROUTE = createRoute({
  method: 'GET',
  path: '/channels/platforms',
  responseType: 'json',
  responseSchema: listChannelPlatformsResponseSchema,
  summary: 'List channel platforms',
  description: 'Returns available channel platforms and their configuration status',
  tags: ['Channels'],
  requiresAuth: true,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Grant the calling user/agent a scoped permission with resource 'channels' and action 'write' (or 'connect'/'disconnect' equivalents your role config uses)
  2. Ensure the request carries valid authentication so getCallerAuthorId or MASTRA_USER_KEY resolves an identity
  3. Use an identity with admin bypass for the 'channels' resource if admin access is intended
  4. If the deployment intentionally has no auth, verify auth is not partially configured, which disables the pass-through

Example fix

// before
await fetch('/api/channels/slack/connect', { method: 'POST', body }) // no auth header
// after
await fetch('/api/channels/slack/connect', { method: 'POST', body, headers: { Authorization: `Bearer ${token}` } }) // token has channels:write
Defensive patterns

Strategy: validation

Validate before calling

const hasChannelsWrite = permissions.some(p => p.resource === 'channels' && ['write','connect','disconnect'].includes(p.action));
if (!hasChannelsWrite) throw new Error('Caller lacks channels:write permission');

Type guard

function canWriteChannels(perms: Array<{resource: string; action: string}> | undefined): boolean {
  return Array.isArray(perms) && perms.some(p => p.resource === 'channels' && p.action === 'write');
}

Try / catch

try {
  await client.connectChannel({ platform, agentId });
} catch (e) {
  if (e.status === 404) {
    // authorization hidden as 404: check identity + channels:write permission
    console.error('Not authorized for channel operations or channel absent:', e.message);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the CONNECT or DISCONNECT channel route (POST connect/disconnect for a platform+agentId) while: (1) the request context lacks a caller author ID AND a MASTRA_USER_KEY user, in an auth-configured deployment; (2) the caller has no scoped permission {resource:'channels', action:'write'}; (3) admin bypass 'channels' is not enabled.

Common situations: Calling the server API with a missing or expired auth token so no identity is resolved; an API key or user scoped only to read permissions being used to connect/disconnect channels; RBAC roles that grant agents:write but not channels:write; tests or scripts hitting the route without forwarding the request context.

Related errors


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