windmill-labs/windmill · error

Diff at index ${index}: old_string "${old_string}" not found

Error message

Diff at index ${index}: old_string "${old_string}" not found in code

What it means

Diffs are applied sequentially with String.replace against the evolving script code. If a diff's old_string does not occur in the current (partially patched) code, the tool throws, naming the diff index and the unmatched string.

Source

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

				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) {
					updatedCode = updatedCode.replaceAll(old_string, new_string)
				} else {
					updatedCode = updatedCode.replace(old_string, new_string)
				}
			}

			// Apply the code changes directly
			await helpers.applyCode(updatedCode, { applyAll: true, mode: 'apply' })

			// Show revert mode
			await helpers.applyCode(oldCode, { mode: 'revert' })

			toolCallbacks.setToolStatus(toolId, {
				content: `Code changes applied`,
				result: 'Success'

View on GitHub (pinned to e474e8803c)

Solutions

  1. Re-read the current script code and regenerate diffs whose old_string exactly matches it (exact whitespace and indentation)
  2. Split large edits into smaller, uniquely-anchored diffs applied in order
  3. Ensure earlier diffs in the array don't consume the text a later old_string expects
  4. If replace was intended for all occurrences, set replace_all: true and confirm old_string matches every intended site

Example fix

// before — indentation mismatch
{ old_string: 'if (x) {\nreturn 1', new_string: '...' } // not found
// after — exact match from current code
{ old_string: '\tif (x) {\n\t\treturn 1', new_string: '...' }
Defensive patterns

Strategy: validation

Validate before calling

const missing = diffs.findIndex(d => !updatedCode.includes(d.old_string))
if (missing !== -1) {
  // re-read current code and regenerate diff at index `missing`
}

Try / catch

try {
  applyDiffs(code, diffs)
} catch (e) {
  if (/not found in code/.test(e.message)) {
    // re-fetch current script code, rebuild exact old_string, retry once
  }
}

Prevention

When it happens

Trigger: old_string doesn't byte-match the editor code — wrong whitespace/indentation, stale code (editor changed since the model read it), the string was already replaced by an earlier diff in the same batch, or the model hallucinated the snippet.

Common situations: Model quoting normalized/fuzzy-matched code instead of exact text; consecutive diffs whose earlier replacement altered text a later diff expected; editing a script whose saved version differs from what the model saw.

Related errors


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