{"record":{"id":"2a78fa784bb1dd3c","repo":"mastra-ai/mastra","slug":"invalid-plan-path","errorCode":null,"errorMessage":"Invalid plan path","messagePattern":"Invalid plan path","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"packages/server/src/server/handlers/plans.ts","lineNumber":47,"sourceCode":"  description:\n    'Returns a markdown plan when the agent exposes the core submit_plan capability and the path is under .mastracode/plans/.',\n  tags: ['Agents', 'Tools'],\n  requiresAuth: true,\n  requiresPermission: MastraFGAPermissions.AGENTS_READ,\n  handler: async ({ agentId, mastra, path, requestContext, status, versionId }) => {\n    try {\n      const versionOptions = versionId ? { versionId } : status ? { status } : undefined;\n      const agent = await getAgentFromSystem({ mastra, agentId, versionOptions, requestContext });\n      const tools = await agent.listTools({ requestContext });\n      const hasSubmitPlan = Object.values(tools).some(\n        tool => typeof tool === 'object' && tool !== null && 'id' in tool && tool.id === submitPlanTool.id,\n      );\n\n      if (!hasSubmitPlan) {\n        throw new HTTPException(404, { message: 'Plan capability not found' });\n      }\n      if (!isPlanPath(path)) {\n        throw new HTTPException(400, { message: 'Invalid plan path' });\n      }\n\n      const workspace = await agent.getWorkspace({ requestContext });\n      const filesystem = await workspace?.resolveFilesystem({ requestContext });\n      if (!filesystem) {\n        throw new HTTPException(404, { message: 'No workspace filesystem configured' });\n      }\n      if (!(await filesystem.exists(path))) {\n        throw new HTTPException(404, { message: `Plan file \"${path}\" not found` });\n      }\n\n      const content = await filesystem.readFile(path, { encoding: 'utf-8' });\n      return {\n        path,\n        content: typeof content === 'string' ? content : content.toString('utf-8'),\n      };\n    } catch (error) {\n      return handleError(error, 'Error reading submitted plan');","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/plans.ts#L29-L65","documentation":"After confirming the agent has the plan tool, the plans handler validates the requested file path with `isPlanPath(path)`; paths that don't match the allowed plan-file convention throw a 400 'Invalid plan path'. This guards reads/writes to only designated plan files within the workspace.","triggerScenarios":"Calling a plan API with a path outside the accepted plan directory/extension (e.g. 'notes.md' instead of the plan path pattern, absolute paths, path traversal attempts, or missing the required prefix like 'plan.md').","commonSituations":"Hardcoding a path that doesn't match the plan convention; using backslashes on Windows-style paths; trying to read arbitrary workspace files through the plan endpoint; upstream components writing a different plan filename than the handler expects.","solutions":["Use the exact plan path convention the handler expects (the isPlanPath-accepted pattern, e.g. the designated plan file name).","Log/inspect the path being sent and compare it against isPlanPath's pattern.","Normalize path separators to forward slashes and avoid absolute paths.","If you need arbitrary files, use the workspace file APIs instead of plan endpoints."],"exampleFix":"// before\nawait getPlan('agent-1', '/tmp/other-plan.md'); // rejected\n// after\nawait getPlan('agent-1', 'plan.md'); // matches isPlanPath convention","handlingStrategy":"validation","validationCode":"const PLAN_PATH = /^plan\\.md$/; // match isPlanPath convention\nif (!PLAN_PATH.test(path)) throw new Error(`'${path}' is not a valid plan path`);","typeGuard":"function isPlanFilePath(path: string): path is 'plan.md' {\n  return path === 'plan.md';\n}","tryCatchPattern":"try {\n  return await getPlan(agentId, path);\n} catch (e) {\n  if (e.status === 400 && e.message === 'Invalid plan path') {\n    console.error(`Path '${path}' violates the plan path convention`);\n    return null;\n  }\n  throw e;\n}","preventionTips":["Centralize the plan path constant and reuse it in every caller.","Use forward slashes and relative paths only.","Never route arbitrary workspace reads through plan endpoints."],"tags":["http-400","validation","plans","paths"],"backgroundTag":"invalid-path","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}