wavetermdev/waveterm · error
edit %d (%s): %s
Error message
edit %d (%s): %s
What it means
ApplyEdits applies a list of EditSpec operations in order; if any edit does not apply (e.g. its search text was not found), the whole batch is aborted and this error reports the edit index, its description, and the underlying reason. No partial application happens through this path (use ReplaceInFilePartial for partial application).
Source
Thrown at pkg/util/fileutil/fileutil.go:304
result.Error = fmt.Sprintf("old_str appears %d times, must appear exactly once", count)
return content, result
}
modifiedContent := bytes.Replace(content, oldBytes, []byte(edit.NewStr), 1)
result.Applied = true
return modifiedContent, result
}
// ApplyEdits applies a series of edits to the given content and returns the modified content.
// This is atomic - all edits succeed or all fail.
func ApplyEdits(originalContent []byte, edits []EditSpec) ([]byte, error) {
modifiedContents := originalContent
for i, edit := range edits {
var result EditResult
modifiedContents, result = applyEdit(modifiedContents, edit, i)
if !result.Applied {
return nil, fmt.Errorf("edit %d (%s): %s", i, result.Desc, result.Error)
}
}
return modifiedContents, nil
}
// ApplyEditsPartial applies edits incrementally, continuing until the first failure.
// Returns the modified content (potentially partially applied) and results for each edit.
func ApplyEditsPartial(originalContent []byte, edits []EditSpec) ([]byte, []EditResult) {
modifiedContents := originalContent
results := make([]EditResult, len(edits))
failed := false
for i, edit := range edits {
if failed {
results[i].Desc = edit.Desc
if results[i].Desc == "" {
results[i].Desc = fmt.Sprintf("Edit %d", i+1)View on GitHub (pinned to a4447c1563)
Solutions
- Re-read the current file content and regenerate the edit with the exact current text.
- Check the reported edit index and Desc to find which EditSpec failed; fix its search string.
- Split the batch and run edits individually to isolate the failing one.
- Use ReplaceInFilePartial if you want earlier edits to be applied despite a later failure.
Example fix
// before
edits := []fileutil.EditSpec{{Search: "oldPort := 8080"}} // no longer in file
_, err := fileutil.ApplyEdits(contents, edits)
// after
contents, _ := os.ReadFile(path)
if !strings.Contains(string(contents), "oldPort := 8080") {
return errors.New("file changed; refresh edit search text")
}
_, err := fileutil.ApplyEdits(contents, edits) Defensive patterns
Strategy: validation
Validate before calling
// verify each edit's search text exists before applying
for _, e := range edits {
if !strings.Contains(string(contents), e.Search) {
return fmt.Errorf("search text %q not found in file", e.Search)
}
} Try / catch
// Go: identify the failing edit from the message
if _, err := fileutil.ApplyEdits(contents, edits); err != nil {
var idx int
if n, _ := fmt.Sscanf(err.Error(), "edit %d", &idx); n == 1 {
log.Printf("edit #%d failed: %v", idx, err)
// regenerate edits[idx] from fresh file content and retry
}
} Prevention
- Always generate edit search text from freshly read file content
- Include enough context in search strings to keep matches unique
- Test edits against the current file version, not a cached snapshot
- Use ReplaceInFilePartial when partial application is acceptable
When it happens
Trigger: Calling ReplaceInFile/EditTextFileDryRun with an EditSpec whose search string does not match the current content, matches ambiguously where uniqueness was required, or is otherwise rejected by applyEdit; the failing edit is identified by its zero-based index in the edits slice.
Common situations: Editing a file whose content changed since the edit was drafted (stale search text); whitespace/indentation mismatches; edits computed against a different file version; duplicate search strings when a unique match is required.
Related errors
- invalid AIMessage: %w
- part %d: text type requires non-empty text field
- invalid format of user@host argument
- file info is required
- invalid object reference: %q
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/2b96080693033504.
Report an issue: GitHub.