mastra-ai/mastra · error · HTTPException
Plan capability not found
Error message
Plan capability not found
What it means
The plans handler inspects the agent's available tools via `agent.listTools()` and requires the submit-plan tool to be present; if the agent lacks that tool capability it throws a 404 'Plan capability not found'. The plan endpoints only work for agents configured with plan-mode tooling.
Source
Thrown at packages/server/src/server/handlers/plans.ts:44
queryParamSchema: agentPlanQuerySchema,
responseSchema: agentPlanResponseSchema,
summary: 'Read a submitted agent plan',
description:
'Returns a markdown plan when the agent exposes the core submit_plan capability and the path is under .mastracode/plans/.',
tags: ['Agents', 'Tools'],
requiresAuth: true,
requiresPermission: MastraFGAPermissions.AGENTS_READ,
handler: async ({ agentId, mastra, path, requestContext, status, versionId }) => {
try {
const versionOptions = versionId ? { versionId } : status ? { status } : undefined;
const agent = await getAgentFromSystem({ mastra, agentId, versionOptions, requestContext });
const tools = await agent.listTools({ requestContext });
const hasSubmitPlan = Object.values(tools).some(
tool => typeof tool === 'object' && tool !== null && 'id' in tool && tool.id === submitPlanTool.id,
);
if (!hasSubmitPlan) {
throw new HTTPException(404, { message: 'Plan capability not found' });
}
if (!isPlanPath(path)) {
throw new HTTPException(400, { message: 'Invalid plan path' });
}
const workspace = await agent.getWorkspace({ requestContext });
const filesystem = await workspace?.resolveFilesystem({ requestContext });
if (!filesystem) {
throw new HTTPException(404, { message: 'No workspace filesystem configured' });
}
if (!(await filesystem.exists(path))) {
throw new HTTPException(404, { message: `Plan file "${path}" not found` });
}
const content = await filesystem.readFile(path, { encoding: 'utf-8' });
return {
path,
content: typeof content === 'string' ? content : content.toString('utf-8'),View on GitHub (pinned to 75dd419e61)
Solutions
- Add the submit-plan tool to the agent's tool configuration (or enable plan mode on the agent).
- Verify you're targeting the correct agent ID that has plan capabilities.
- Check any dynamic tool filtering (requestContext-based tools) that may exclude the submit-plan tool at runtime.
- Inspect `agent.listTools()` output locally to confirm the plan tool id is present before calling the API.
Example fix
// before
new Agent({ name: 'planner', instructions: '...', tools: {} });
// after
import { submitPlanTool } from '@mastra/core/tools';
new Agent({ name: 'planner', instructions: '...', tools: { submitPlan: submitPlanTool } }); Defensive patterns
Strategy: type-guard
Validate before calling
const tools = await agent.listTools({ requestContext });
const hasPlanTool = Object.values(tools).some(
(t): t is { id: string } => !!t && typeof t === 'object' && 'id' in t && t.id === submitPlanTool.id,
);
if (!hasPlanTool) throw new Error('Agent lacks plan capability'); Type guard
function isToolWithId(t: unknown): t is { id: string } {
return typeof t === 'object' && t !== null && 'id' in t && typeof (t as any).id === 'string';
} Try / catch
try {
return await getPlan(agentId, path);
} catch (e) {
if (e.status === 404 && e.message.includes('capability')) {
console.error('Enable plan tools on this agent first');
return null;
}
throw e;
} Prevention
- Only expose plan UI/endpoints for agents verified to include the submit-plan tool.
- Check dynamic tool filtering doesn't exclude the plan tool at runtime.
- Pin agent definitions with plan tools in a shared factory function.
When it happens
Trigger: Calling a plan read/write API for an agent whose toolset does not include the submitPlanTool — agent created without plan-mode tools, tools filtered out by dynamic tool selection/model gating, or wrong agent ID used in the request.
Common situations: Pointing plan APIs at a plain agent that never got the plan tool; tool allowlists in model/provider config excluding the plan tool; an older agent definition predating plan-mode support.
Related errors
- Model "${modelId}" is not available. Available models: ${ids
- ClaudeSDKAgent resumeData must include either sessionId or c
- Agent with id ${agentId} not found
- Model config with id ${modelConfigId} not found
- Agent "${agentId}" not found
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/d3d655fd584b098d.
Report an issue: GitHub.