windmill-labs/windmill · error

Diffs parameter is required and must be an array

Error message

Diffs parameter is required and must be an array

What it means

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.

Source

Thrown at frontend/src/lib/components/copilot/chat/script/core.ts:791

	fn: async function ({ args, helpers, toolCallbacks, toolId }) {
		const scriptOptions = helpers.getScriptOptions()

		if (!scriptOptions) {
			toolCallbacks.setToolStatus(toolId, {
				content: 'No script available to edit',
				error: 'No script found in current context'
			})
			throw new Error(
				'No script code available to edit. Please ensure you have a script open in the editor.'
			)
		}

		if (!args.diffs || !Array.isArray(args.diffs)) {
			toolCallbacks.setToolStatus(toolId, {
				content: 'Invalid diffs provided',
				error: 'Diffs parameter is required and must be an array'
			})
			throw new Error('Diffs parameter is required and must be an array')
		}

		toolCallbacks.setToolStatus(toolId, { content: 'Applying code changes...' })

		try {
			// Save old code
			const oldCode = scriptOptions.code

			// Apply diffs sequentially
			let updatedCode = oldCode
			for (const [index, diff] of args.diffs.entries()) {
				const { old_string, new_string, replace_all = false } = diff

				if (!updatedCode.includes(old_string)) {
					throw new Error(`Diff at index ${index}: old_string "${old_string}" not found in code`)
				}

				if (replace_all) {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Re-invoke the tool with diffs as a proper array, e.g. [{ old_string: '...', new_string: '...' }]
  2. If the model returned a single diff object, wrap it in an array before calling
  3. Re-prompt the model to emit the diffs array in the documented schema

Example fix

// before
{ diffs: { old_string: 'a', new_string: 'b' } } // not an array
// after
{ diffs: [{ old_string: 'a', new_string: 'b' }] }
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(args.diffs)) {
  // normalize: wrap single object, or parse JSON string, before calling
}

Type guard

function isDiffArray(v) {
  return Array.isArray(v) && v.every(d => typeof d?.old_string === 'string' && typeof d?.new_string === 'string')
}

Prevention

When it happens

Trigger: The model produces diffs as a single object, a JSON string, or omits the field entirely; callers passing null/undefined diffs.

Common situations: 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.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/712319befbca3e2f. Report an issue: GitHub.