{"record":{"id":"10c7f53d8e7551ef","repo":"mastra-ai/mastra","slug":"agent-fs-routing-subagent-description-required","errorCode":"AGENT_FS_ROUTING_SUBAGENT_DESCRIPTION_REQUIRED","errorMessage":"Agent \"${name}\": subagent \"${childId}\" requires a non-empty 'description'. Set one in agents/${name}/subagents/${childId}/config.ts.","messagePattern":"Agent \"(.+?)\": subagent \"(.+?)\" requires a non-empty 'description'\\. Set one in agents/(.+?)/subagents/(.+?)/config\\.ts\\.","errorType":"error_code","errorClass":"MastraError","httpStatus":null,"severity":"error","filePath":"packages/core/src/agent/fs-routing/index.ts","lineNumber":660,"sourceCode":"        text: `Agent \"${name}\": duplicate subagent \"${childId}\" under agents/${name}/subagents/.`,\n      });\n    }\n\n    if (toolKeys.has(childId)) {\n      throw new MastraError({\n        id: 'AGENT_FS_ROUTING_SUBAGENT_NAME_COLLISION',\n        domain: ErrorDomain.AGENT,\n        category: ErrorCategory.USER,\n        details: { agentName: name, subagentName: childId },\n        text: `Agent \"${name}\": subagent \"${childId}\" collides with a tool of the same name. Rename agents/${name}/subagents/${childId}/ or the tool.`,\n      });\n    }\n\n    const child = assembleAtDepth(childEntry, depth + 1, options);\n\n    const description = child.getDescription();\n    if (!description || description.trim() === '') {\n      throw new MastraError({\n        id: 'AGENT_FS_ROUTING_SUBAGENT_DESCRIPTION_REQUIRED',\n        domain: ErrorDomain.AGENT,\n        category: ErrorCategory.USER,\n        details: { agentName: name, subagentName: childId },\n        text: `Agent \"${name}\": subagent \"${childId}\" requires a non-empty 'description'. Set one in agents/${name}/subagents/${childId}/config.ts.`,\n      });\n    }\n\n    if (configKeys.has(childId)) {\n      onWarn(\n        `Agent \"${name}\": subagent \"${childId}\" defined in both config.agents and subagents/; config.agents wins.`,\n      );\n      continue;\n    }\n\n    fromFs[childId] = child;\n  }\n","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent/fs-routing/index.ts#L642-L678","documentation":"mergeSubAgents assembles each filesystem subagent and calls getDescription(); a subagent used for delegation must carry a non-empty description because that text is what the parent agent's model uses to decide when to hand off. Empty, whitespace-only, or missing descriptions cause this USER error at assembly time.","triggerScenarios":"agents/<name>/subagents/<child>/config.ts omitting the `description` field; setting `description: ''` or only whitespace (e.g. `'   '`); constructing a subagent programmatically (via assembleAtDepth path) whose description getter returns empty.","commonSituations":"Scaffolding a new subagent quickly and skipping the description; templated configs where the placeholder string was deleted; refactors that moved description into a shared constant that resolved to an empty string.","solutions":["Add a meaningful `description` to agents/<name>/subagents/<child>/config.ts explaining what the subagent does and when to use it.","Trim-check the value: the description must not be empty or whitespace-only after trim().","If the description comes from a shared constant/import, verify the imported value is actually populated at runtime."],"exampleFix":"// before (agents/main/subagents/researcher/config.ts)\nexport const config = { name: 'researcher', description: '', /* ... */ };\n\n// after\nexport const config = { name: 'researcher', description: 'Searches the web and summarizes findings for research questions.', /* ... */ };","handlingStrategy":"validation","validationCode":"const configs = import.meta.glob('./agents/*/subagents/*/config.ts', { eager: true });\nfor (const [path, mod] of Object.entries(configs)) {\n  const desc = (mod as any).config?.description;\n  if (typeof desc !== 'string' || desc.trim() === '') {\n    throw new Error(`Missing non-empty description in ${path}`);\n  }\n}","typeGuard":"function hasNonEmptyDescription(c: unknown): c is { name: string; description: string } {\n  return typeof c === 'object' && c !== null && 'description' in c &&\n    typeof (c as any).description === 'string' && (c as any).description.trim() !== '';\n}","tryCatchPattern":"try {\n  buildAgentFromFs('main');\n} catch (e) {\n  if (e instanceof MastraError && e.id === 'AGENT_FS_ROUTING_SUBAGENT_DESCRIPTION_REQUIRED') {\n    console.error('Set a description for subagent:', e.detail?.subagentName);\n  } else throw e;\n}","preventionTips":["Include `description` in your subagent scaffold/template","Write descriptions from the model's perspective: what it does and when the parent should delegate","Add a lint/test that every subagent config passes a non-empty trimmed description check","Avoid whitespace-only placeholder descriptions"],"tags":["agent","subagents","validation","config"],"backgroundTag":"missing-required-field","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}