{"record":{"id":"eadbfc98ec1cceb8","repo":"n8n-io/n8n","slug":"no-prompt-found-in-inputs-expected-prompt-stri","errorCode":null,"errorMessage":"No prompt found in inputs - expected \"prompt\" string or \"messages\" array","messagePattern":"No prompt found in inputs - expected \"prompt\" string or \"messages\" array","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/ai-workflow-builder.ee/evaluations/harness/runner.ts","lineNumber":1002,"sourceCode":"\t[key: string]: unknown;\n}\n\n/**\n * Extract prompt from dataset input.\n * Supports both direct prompt and messages array format.\n */\nfunction extractPrompt(inputs: LangsmithDatasetInput): string {\n\t// Direct prompt string\n\tif (inputs.prompt && typeof inputs.prompt === 'string') {\n\t\treturn inputs.prompt;\n\t}\n\n\t// Messages array format\n\tif (inputs.messages && Array.isArray(inputs.messages) && inputs.messages.length > 0) {\n\t\treturn extractMessageContent(inputs.messages[0]);\n\t}\n\n\tthrow new Error('No prompt found in inputs - expected \"prompt\" string or \"messages\" array');\n}\n\n/**\n * Pre-process LangSmith examples to extract conversation history from outputs\n * and inject it into inputs for the target function.\n *\n * The dataset format has:\n * - inputs.messages[0]: The latest user turn\n * - outputs.messages: The FULL conversation (all prior turns + latest + AI response)\n *\n * We find the latest turn in outputs and extract everything before it as historical.\n */\nfunction enrichExamplesWithHistory(examples: Example[]): Example[] {\n\treturn examples.map((example) => {\n\t\tconst outputMessages = (example.outputs as Record<string, unknown> | undefined)?.messages;\n\t\tif (!Array.isArray(outputMessages) || outputMessages.length <= 1) {\n\t\t\treturn example; // No history to extract\n\t\t}","sourceCodeStart":984,"sourceCodeEnd":1020,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/ai-workflow-builder.ee/evaluations/harness/runner.ts#L984-L1020","documentation":"`extractPrompt` reads a single prompt from a LangSmith dataset example's `inputs`. It accepts either a `prompt` string or a non-empty `messages` array (in which case it takes `messages[0]`). If neither shape is present, the example is unusable and the harness aborts. This protects downstream agents from being invoked with an undefined prompt.","triggerScenarios":"A dataset example whose `inputs` has neither a `prompt` field nor a `messages` array — e.g. it only carries `workflowJSON`, custom metadata, or a `messages` array that is empty. Also triggered by malformed examples uploaded with the wrong field names.","commonSituations":"Dataset schema drift (field renamed from `prompt` to `user_prompt`); examples created by a different tool that uses `input`/`query`; an example whose `messages` array was stripped during export; copy-pasting an example and dropping the prompt field.","solutions":["Open the dataset in the LangSmith UI and confirm each example's `inputs` has either a `prompt` string or a non-empty `messages` array.","If your schema uses a different field, either rename it to `prompt` in the dataset or extend `extractPrompt` to read your field.","Filter out malformed examples before running, or fix them in place."],"exampleFix":"// before\n// example.inputs = { workflowJSON: {...} }  (no prompt/messages)\n// after\n// example.inputs = { prompt: \"build a slack notifier\", workflowJSON: {...} }","handlingStrategy":"type-guard","validationCode":"function hasUsablePrompt(inputs: unknown): boolean {\n  if (!inputs || typeof inputs !== 'object') return false;\n  const r = inputs as Record<string, unknown>;\n  if (typeof r.prompt === 'string' && r.prompt.length > 0) return true;\n  return Array.isArray(r.messages) && r.messages.length > 0;\n}\n// filter the dataset up front\nconst usable = examples.filter((e) => hasUsablePrompt(e.inputs));\nif (usable.length === 0) throw new Error('no dataset examples have a prompt or messages array');","typeGuard":"function isPromptableInput(inputs: unknown): inputs is { prompt: string } | { messages: unknown[] } {\n  if (!inputs || typeof inputs !== 'object') return false;\n  const r = inputs as Record<string, unknown>;\n  if (typeof r.prompt === 'string' && r.prompt.length > 0) return true;\n  return Array.isArray(r.messages) && r.messages.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Validate dataset examples in a pre-run lint pass and report which example ids are missing prompts.","Document the accepted input schema (`prompt` string OR `messages` array) next to the dataset upload tool.","Add a contract test that feeds a fixture example without a prompt and asserts the error."],"tags":["langsmith","dataset","validation","types","schema"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}