mastra-ai/mastra · error · HTTPException
agent controller "${controllerId}" not found
Error message
agent controller "${controllerId}" not found What it means
getAgentControllerOrThrow resolves an agent controller via `mastra.getAgentController(controllerId)` and throws HTTP 404 when the mastra instance has no controller registered under that id (or when getAgentController itself is undefined on the instance). It is the shared guard used by all agent-controller HTTP handlers.
Source
Thrown at packages/server/src/server/handlers/agent-controller.ts:73
} satisfies Record<ReservedThreadMetadataKey, true>;
function isReservedThreadMetadataKey(key: string): boolean {
return Object.hasOwn(RESERVED_THREAD_METADATA_KEYS, key) || key.startsWith('modeModelId_');
}
/**
* Resolves a controller by id via the canonical `mastra.getAgentController`
* accessor, throwing a 404 if no controller is registered under that id.
*/
function getAgentControllerOrThrow(
mastra: {
getAgentController?: (id: string) => AgentController<any> | undefined;
},
controllerId: string,
): AgentController<any> {
const controller = mastra.getAgentController?.(controllerId);
if (!controller) {
throw new HTTPException(404, { message: `agent controller "${controllerId}" not found` });
}
return controller;
}
async function getSession(
controller: AgentController<any>,
resourceId: string,
options?: { tags?: Record<string, string>; scope?: string; threadId?: string },
requestContext?: RequestContext,
): Promise<Session<any>> {
await controller.init();
const { tags, scope, threadId } = options ?? {};
// Scoped sessions are independent sessions over the same resource (e.g. one
// per git worktree), so qualify the stable session id with the scope to keep
// their identities distinct as well. An exact thread binding doubles as the
// stable session id when supplied.
const id = threadId ?? (scope ? `${resourceId}::${scope}` : resourceId);
return controller.createSession({ resourceId, id, ownerId: controller.id, tags, scope, threadId, requestContext });View on GitHub (pinned to 75dd419e61)
Solutions
- Fix the controllerId in the request to one registered on the running Mastra instance.
- Register the controller: configure `getAgentController` (and the controllers it returns) on your Mastra instance.
- List available controllers from your server config and have the client pick from that instead of hardcoding ids.
- Redeploy/restart so server code and client expectations reference the same controller set.
Example fix
// before
const c = await api.getAgentControllerSession({ controllerId: 'coders' });
// after
const c = await api.getAgentControllerSession({ controllerId: 'coder' }); // id registered via mastra.getAgentController Defensive patterns
Strategy: validation
Validate before calling
const controllers = await api.listAgentControllers();
if (!controllers.some(c => c.id === controllerId)) {
throw new Error(`Controller '${controllerId}' is not registered on this server`);
} Type guard
function isKnownController(id: string, known: readonly string[]): id is string {
return known.includes(id);
} Try / catch
try {
return await api.getControllerSession({ controllerId });
} catch (e) {
if (isHttpError(e) && e.status === 404 && e.message.includes('agent controller')) {
throw new Error(`Controller '${controllerId}' not found — check registration on the Mastra instance`);
}
throw e;
} Prevention
- Derive controller ids from server metadata instead of hardcoding.
- Keep controller registration and client constants in one module.
- Add a startup check that every id referenced by your UI is registered.
When it happens
Trigger: Any agent-controller endpoint (sessions, threads, objectives, messages) called with a `controllerId` path/body parameter that was never registered on the Mastra instance, e.g. `mastra.getAgentController` not configured or the controller removed/renamed in code.
Common situations: Playground UI or client referencing a controller that exists in another deployment/environment; controller deleted during refactor; server restarted with an updated agent definition so previously valid ids 404; forgetting to register controllers when constructing Mastra.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Vector store ${vectorName} not found
- Model "${modelId}" is not available. Available models: ${ids
- ACP connection is not initialized
- Model "${this.options.model}" is not available. Available mo
- ClaudeSDKAgent resumeData must include either sessionId or c
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b05f62c481aca878.
Report an issue: GitHub.