{"record":{"id":"1de552c42cf94894","repo":"mastra-ai/mastra","slug":"tool-must-have-input-and-output-schemas-defined","errorCode":null,"errorMessage":"Tool must have input and output schemas defined","messagePattern":"Tool must have input and output schemas defined","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/evented/workflow.ts","lineNumber":661,"sourceCode":"      }\n\n      return {\n        text: await textPromise,\n      } as TStepOutput;\n    },\n    component: 'AGENT',\n  };\n}\n\nfunction createStepFromTool<TStepInput, TSuspend, TResume, TStepOutput>(\n  params: ToolStep<TStepInput, TSuspend, TResume, TStepOutput, any>,\n  agentOrToolOptions?: Record<string, unknown>,\n): Step<string, any, TStepInput, TStepOutput, TResume, TSuspend, DefaultEngineType> {\n  const toolOpts = agentOrToolOptions as\n    | { retries?: number; scorers?: DynamicArgument<MastraScorers>; metadata?: StepMetadata }\n    | undefined;\n  if (!params.inputSchema || !params.outputSchema) {\n    throw new Error('Tool must have input and output schemas defined');\n  }\n\n  return {\n    id: params.id,\n    description: params.description,\n    inputSchema: params.inputSchema,\n    outputSchema: params.outputSchema,\n    resumeSchema: params.resumeSchema,\n    suspendSchema: params.suspendSchema,\n    retries: toolOpts?.retries,\n    scorers: toolOpts?.scorers,\n    metadata: toolOpts?.metadata,\n    execute: async ({\n      inputData,\n      mastra,\n      requestContext,\n      suspend,\n      resumeData,","sourceCodeStart":643,"sourceCodeEnd":679,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/evented/workflow.ts#L643-L679","documentation":"createStepFromTool requires the ToolStep to declare both inputSchema and outputSchema so the workflow can validate data flowing in and out of the step. If either schema is missing, this Error is thrown before the step is registered.","triggerScenarios":"createStep(tool) where tool.inputSchema or tool.outputSchema is undefined — e.g. a tool created without schemas, a tool object spread losing schema fields, or a dynamically-built tool whose schema assignment failed.","commonSituations":"Tools written for other frameworks that only define execute; building tools conditionally at runtime and forgetting schemas; TypeScript types relaxed to any hiding the missing fields.","solutions":["Define both inputSchema and outputSchema on the tool (z.object(...) or any Standard Schema).","If the tool genuinely has no input/output, use z.object({}) rather than leaving the fields undefined.","Confirm the object passed is the full tool (not a destructured subset like just its execute function)."],"exampleFix":"// before\nconst tool = { id: 'weather', execute: async ({ context }) => getWeather(context.city) };\ncreateStep(tool);\n\n// after\nconst tool = {\n  id: 'weather',\n  inputSchema: z.object({ city: z.string() }),\n  outputSchema: z.object({ temp: z.number() }),\n  execute: async ({ context }) => ({ temp: await getWeather(context.city) }),\n};\ncreateStep(tool);","handlingStrategy":"validation","validationCode":"function assertToolSchemas(tool: { id: string; inputSchema?: unknown; outputSchema?: unknown }) {\n  if (!tool.inputSchema || !tool.outputSchema) {\n    throw new Error(`Tool ${tool.id} must define inputSchema and outputSchema before createStep(tool)`);\n  }\n}","typeGuard":"const hasSchemas = (t: any): t is { inputSchema: object; outputSchema: object } =>\n  t?.inputSchema != null && t?.outputSchema != null;","tryCatchPattern":"try {\n  return createStep(tool);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Tool must have input and output schemas defined') {\n    throw new Error(`Tool '${(tool as any)?.id}' is missing schemas`);\n  }\n  throw e;\n}","preventionTips":["Type tool definitions with zod schemas on both input and output at authoring time.","Use z.object({}) for empty input/output instead of omitting the fields.","Add a unit test that creates steps from every registered tool at startup."],"tags":["tool","schema","validation","workflow"],"backgroundTag":"missing-tool-schemas","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}