continuedev/continue · error · ContinueError

FindAndReplaceIdenticalOldAndNewStrings

FindAndReplaceIdenticalOldAndNewStrings

Error message

${context}old_string and new_string must be different

What it means

Thrown by validateSingleEdit when the old_string and new_string passed to a find-and-replace edit are exactly equal. The library rejects no-op edits because applying them would silently do nothing and likely indicates the caller constructed the edit incorrectly. It is part of the search/replace edit argument validation layer.

Source

Thrown at core/edit/searchAndReplace/findAndReplaceUtils.ts:30

  replaceAll: unknown,
  index?: number,
): { oldString: string; newString: string; replaceAll?: boolean } {
  const context = index !== undefined ? `edit at index ${index}: ` : "";

  if (oldString === undefined || typeof oldString !== "string") {
    throw new ContinueError(
      ContinueErrorReason.FindAndReplaceMissingOldString,
      `${context}string old_string is required`,
    );
  }
  if (newString === undefined || typeof newString !== "string") {
    throw new ContinueError(
      ContinueErrorReason.FindAndReplaceMissingNewString,
      `${context}string new_string is required`,
    );
  }
  if (oldString === newString) {
    throw new ContinueError(
      ContinueErrorReason.FindAndReplaceIdenticalOldAndNewStrings,
      `${context}old_string and new_string must be different`,
    );
  }
  if (replaceAll !== undefined && typeof replaceAll !== "boolean") {
    throw new ContinueError(
      ContinueErrorReason.FindAndReplaceInvalidReplaceAll,
      `${context}replace_all must be a valid boolean`,
    );
  }
  return { oldString, newString, replaceAll };
}

export function trimEmptyLines({
  lines,
  fromEnd,
}: {
  lines: string[];

View on GitHub (pinned to 5522c6f44c)

Solutions

  1. Change new_string so it differs from old_string (including whitespace)
  2. If you intended to delete the string, set new_string to "" and old_string to the text to remove
  3. If you intended an insertion, use an empty old_string only as the first edit with the inserted text as new_string

Example fix

// before
await findAndReplace({ filepath, old_string: "foo", new_string: "foo" });
// after
await findAndReplace({ filepath, old_string: "foo", new_string: "bar" });
Defensive patterns

Strategy: validation

Validate before calling

if (edit.oldString === edit.newString) throw new TypeError('old_string and new_string must differ');

Type guard

const isValidEdit = (e: { old_string: string; new_string: string }) => e.old_string !== e.new_string;

Try / catch

catch (e) { if (e.message.includes('must be different')) skipNoOpEdit(e); else throw e; }

Prevention

When it happens

Trigger: Calling find_and_replace (or multi-edit) with edit.old_string === edit.new_string, e.g. both set to "foo" or both set to "".

Common situations: LLM agents generating an edit that 'changes' a string to itself; templating code that interpolates the same variable into both fields; copy-paste of the old string into the new string slot.

Related errors


AI-assisted analysis of continuedev/continue@5522c6f44c (2026-08-27). Data as JSON: /api/errors/e19576add1ec2d41. Report an issue: GitHub.