windmill-labs/windmill · error
old_string matched ${matchCount} locations. Make it more spe
Error message
old_string matched ${matchCount} locations. Make it more specific or set replace_all to true. What it means
findAndReplace requires old_string to be unique unless replaceAll is set. When the literal old_string occurs more than once and replaceAll is false, it throws this error with the exact match count so the caller (usually the model) can disambiguate. This guards against unintended edits at multiple locations.
Source
Thrown at frontend/src/lib/components/copilot/chat/shared.ts:311
/**
* Match-count-validated exact text replacement. Throws when `oldString` is
* missing, and (unless `replaceAll`) when it appears more than once.
* `contextLabel` flows into the error message ("not found in the <label>.").
*/
export function findAndReplace(
content: string,
oldString: string,
newString: string,
replaceAll: boolean,
contextLabel: string
): string {
const matchCount = countExactMatches(content, oldString)
if (matchCount === 0) {
throw new Error(`old_string was not found in the ${contextLabel}.`)
}
if (!replaceAll && matchCount !== 1) {
throw new Error(
`old_string matched ${matchCount} locations. Make it more specific or set replace_all to true.`
)
}
return applyExactReplace(content, oldString, newString, replaceAll)
}
export const extractAllModules = (modules: FlowModule[]): FlowModule[] => {
return modules.flatMap((m) => {
if (m.value.type === 'forloopflow' || m.value.type === 'whileloopflow') {
return [m, ...extractAllModules(m.value.modules)]
}
if (m.value.type === 'branchall') {
return [m, ...extractAllModules(m.value.branches.flatMap((b) => b.modules))]
}
if (m.value.type === 'branchone') {
return [
m,
...extractAllModules([...m.value.branches.flatMap((b) => b.modules), ...m.value.default])View on GitHub (pinned to e474e8803c)
Solutions
- Include more surrounding lines in old_string so it matches exactly one location, then retry.
- If all occurrences should change, set replace_all: true on the tool call.
- Replace a larger unique block that contains the target line as one edit.
- Split the edit into multiple calls, each with context that makes the target occurrence unique.
Example fix
// before
findAndReplace(content, "return null", "return undefined", false, "the file") // 3 matches
// after
findAndReplace(content, "if (!user) {\n\treturn null\n}", "if (!user) {\n\treturn undefined\n}", false, "the file") Defensive patterns
Strategy: validation
Validate before calling
const count = content.split(oldString).length - 1
if (!replaceAll && count > 1) {
throw new Error(`old_string matches ${count} places; add surrounding context or set replace_all`)
} Try / catch
try {
return findAndReplace(content, oldString, newString, replaceAll, 'the file')
} catch (e) {
const m = e.message.match(/matched (\d+) locations/)
if (m) {
const widened = widenWithSurroundingContext(content, oldString, 3)
return findAndReplace(content, widened, replaceSnippet(newString), false, 'the file')
}
throw e
} Prevention
- Make old_string long enough to be unique (include enclosing function or block lines).
- Count occurrences with content.split(oldString).length - 1 before calling.
- Set replace_all: true deliberately when every occurrence should change.
- Avoid editing generic patterns like bare braces or repeated imports without context.
When it happens
Trigger: An edit tool passed a short or generic old_string (e.g. '});', a repeated variable assignment, or a common import line) that matches N>1 places, with replace_all=false. countExactMatches found multiple occurrences in the file or flow JSON.
Common situations: Model tries to edit a common pattern like a closing brace, a repeated import, or 'return null' that exists in several functions; user asks to change one occurrence of a duplicated block; generated code contains two identical placeholder lines.
Related errors
- old_string was not found in the ${contextLabel}.
- ⚠️ WARNING: Multiple workspaces map to git branch '${branch
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/2236ad27463d0eb0.
Report an issue: GitHub.