{"record":{"id":"ee47c4963c3bba9e","repo":"FlowiseAI/Flowise","slug":"received-tool-input-did-not-match-expected-schema-ee47c4","errorCode":null,"errorMessage":"Received tool input did not match expected schema","messagePattern":"Received tool input did not match expected schema","errorType":"validation","errorClass":"ToolInputParsingException","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/tools/RetrieverTool/RetrieverTool.ts","lineNumber":63,"sourceCode":"    constructor(fields: DynamicStructuredToolInput<T>) {\n        super(fields)\n        this.name = fields.name\n        this.description = fields.description\n        this.func = fields.func\n        this.returnDirect = fields.returnDirect ?? this.returnDirect\n        this.schema = fields.schema\n    }\n\n    async call(arg: any, configArg?: RunnableConfig | Callbacks, tags?: string[], flowConfig?: IFlowConfig): Promise<string> {\n        const config = parseCallbackConfigArg(configArg)\n        if (config.runName === undefined) {\n            config.runName = this.name\n        }\n        let parsed\n        try {\n            parsed = await parseWithTypeConversion(this.schema, arg)\n        } catch (e) {\n            throw new ToolInputParsingException(`Received tool input did not match expected schema`, JSON.stringify(arg))\n        }\n        const callbackManager_ = await CallbackManager.configure(\n            config.callbacks,\n            this.callbacks,\n            config.tags || tags,\n            this.tags,\n            config.metadata,\n            this.metadata,\n            { verbose: this.verbose }\n        )\n        const runManager = await callbackManager_?.handleToolStart(\n            this.toJSON(),\n            typeof parsed === 'string' ? parsed : JSON.stringify(parsed),\n            undefined,\n            undefined,\n            undefined,\n            undefined,\n            config.runName","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/tools/RetrieverTool/RetrieverTool.ts#L45-L81","documentation":"Thrown by RetrieverTool.call when parseWithTypeConversion fails to coerce the incoming `arg` against the tool's `schema`. The arg is forwarded as-is into the error's data field via JSON.stringify. This is a tool-input contract violation: the caller (often an LLM agent) sent a payload the retriever cannot interpret.","triggerScenarios":"An agent invokes the retriever with a free-form string when the schema expects an object (or vice versa); required fields missing; field types mismatch (e.g. number vs string); extra fields when additionalProperties is false and coercion is strict.","commonSituations":"Agent prompt does not describe the tool schema accurately; the retriever wraps a vector store whose schema changed; LLM hallucinated the input shape; legacy flows after a schema migration.","solutions":["Inspect this.schema on the RetrieverTool instance and align the agent's output to it.","Update the agent's system prompt to include the exact JSON shape the retriever expects.","If using LangChain function-calling, bind the tool via `bindTools` so the model sees the schema.","Pre-parse and normalize the arg before invoking call()."],"exampleFix":"// before\nconst retriever = new RetrieverTool({ schema: z.object({ query: z.string(), k: z.number() }), ... })\nawait retriever.call('search term') // throws: Received tool input did not match expected schema\n\n// after\nawait retriever.call({ query: 'search term', k: 4 })","handlingStrategy":"type-guard","validationCode":"async function safeRetrieverCall(tool: any, arg: unknown) {\n  // Pre-validate against the tool's schema if it exposes safeParse (zod)\n  if (tool.schema?.safeParse) {\n    const r = tool.schema.safeParse(arg)\n    if (!r.success) throw new Error(`Arg rejected pre-call: ${r.error.message}`)\n  }\n  return tool.call(arg)\n}","typeGuard":"import { z } from 'zod'\nconst retrieverInput = z.object({ query: z.string(), k: z.number().int().positive().optional() })\nconst isRetrieverInput = (x: unknown): x is z.infer<typeof retrieverInput> =>\n  retrieverInput.safeParse(x).success","tryCatchPattern":"try {\n  return await retriever.call(arg)\n} catch (e) {\n  if (/did not match expected schema/i.test((e as Error).message)) {\n    throw new Error(`Agent sent invalid retriever input: ${JSON.stringify(arg)}`)\n  }\n  throw e\n}","preventionTips":["Bind the retriever schema to the agent via `bindTools`/function-calling so the model sees it.","Describe the exact JSON shape in the agent's system prompt.","Pre-parse free-text agent output into the schema before calling the tool.","Keep a regression test that exercises the retriever with the agent's actual output shape."],"tags":["schema","validation","parsing","agent","retriever"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}