{"record":{"id":"712319befbca3e2f","repo":"windmill-labs/windmill","slug":"diffs-parameter-is-required-and-must-be-an-array","errorCode":null,"errorMessage":"Diffs parameter is required and must be an array","messagePattern":"Diffs parameter is required and must be an array","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/script/core.ts","lineNumber":791,"sourceCode":"\tfn: async function ({ args, helpers, toolCallbacks, toolId }) {\n\t\tconst scriptOptions = helpers.getScriptOptions()\n\n\t\tif (!scriptOptions) {\n\t\t\ttoolCallbacks.setToolStatus(toolId, {\n\t\t\t\tcontent: 'No script available to edit',\n\t\t\t\terror: 'No script found in current context'\n\t\t\t})\n\t\t\tthrow new Error(\n\t\t\t\t'No script code available to edit. Please ensure you have a script open in the editor.'\n\t\t\t)\n\t\t}\n\n\t\tif (!args.diffs || !Array.isArray(args.diffs)) {\n\t\t\ttoolCallbacks.setToolStatus(toolId, {\n\t\t\t\tcontent: 'Invalid diffs provided',\n\t\t\t\terror: 'Diffs parameter is required and must be an array'\n\t\t\t})\n\t\t\tthrow new Error('Diffs parameter is required and must be an array')\n\t\t}\n\n\t\ttoolCallbacks.setToolStatus(toolId, { content: 'Applying code changes...' })\n\n\t\ttry {\n\t\t\t// Save old code\n\t\t\tconst oldCode = scriptOptions.code\n\n\t\t\t// Apply diffs sequentially\n\t\t\tlet updatedCode = oldCode\n\t\t\tfor (const [index, diff] of args.diffs.entries()) {\n\t\t\t\tconst { old_string, new_string, replace_all = false } = diff\n\n\t\t\t\tif (!updatedCode.includes(old_string)) {\n\t\t\t\t\tthrow new Error(`Diff at index ${index}: old_string \"${old_string}\" not found in code`)\n\t\t\t\t}\n\n\t\t\t\tif (replace_all) {","sourceCodeStart":773,"sourceCodeEnd":809,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/script/core.ts#L773-L809","documentation":"Thrown by the edit_script tool in the script AI chat when `args.diffs` is missing or not an array. The tool applies structured diff hunks to the open script; a malformed diffs argument cannot be applied. A matching tool-status error is set before throwing so the model sees and can correct its malformed tool call.","triggerScenarios":"The model produces diffs as a single object, a JSON string, or omits the field entirely; callers passing null/undefined diffs.","commonSituations":"LLM output parsing degraded the patches into a string; prompt asked for one replacement so the model sent a bare object; intermediary serialized the args incorrectly.","solutions":["Re-invoke the tool with diffs as a proper array, e.g. [{ old_string: '...', new_string: '...' }]","If the model returned a single diff object, wrap it in an array before calling","Re-prompt the model to emit the diffs array in the documented schema"],"exampleFix":"// before\n{ diffs: { old_string: 'a', new_string: 'b' } } // not an array\n// after\n{ diffs: [{ old_string: 'a', new_string: 'b' }] }","handlingStrategy":"validation","validationCode":"if (!Array.isArray(args.diffs)) {\n  // normalize: wrap single object, or parse JSON string, before calling\n}","typeGuard":"function isDiffArray(v) {\n  return Array.isArray(v) && v.every(d => typeof d?.old_string === 'string' && typeof d?.new_string === 'string')\n}","tryCatchPattern":null,"preventionTips":["Validate tool arguments against the schema before dispatch","Instruct the model to always emit diffs as an array","Normalize single-diff objects into arrays at the call boundary"],"tags":["validation","ai-copilot","arguments","diffs"],"backgroundTag":"invalid-tool-arguments","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}