kopia/kopia · error

error parsing edited file

Error message

error parsing edited file

What it means

After each editor run, EditLoop calls readAndStripComments to re-read the temp file and strip '#' comment lines. This error wraps failures reading that file (see also errors 875/876 which wrap the same call's inner errors before reaching here). It signals the edited file could not be opened or read back.

Solutions

  1. Configure an editor that edits the file in place rather than replacing/renaming it.
  2. Exclude kopia temp paths from background tmp-cleaners.
  3. Retry the command; if reproducible, inspect the wrapped cause for the underlying read/open error.

Example fix

// before
export EDITOR="my-script"  # script writes result to a new file path
// after
export EDITOR="my-script"  # script must edit $1 in place
Defensive patterns

Strategy: try-catch

Validate before calling

if fi, err := os.Stat(tmpFile); err != nil || fi.Size() == 0 {
    // file vanished before read-back; re-run the edit loop
}

Try / catch

if err := editor.EditLoop(ctx, fname, initial, false, parse); err != nil {
    if errors.Is(err, fs.ErrNotExist) { return errors.New("edited file was deleted; check your editor/wrapper") }
    return err
}

Prevention

When it happens

Trigger: readAndStripComments(tmpFile, withComments) returns an error inside EditLoop — file missing (deleted by editor or tmp cleaner) or unreadable at read-back time.

Common situations: A wrapper EDITOR command moves/renames the file instead of editing in place; a tmp cleaner deletes the temp dir during a long editing session; filesystem errors on read.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07). Data as JSON: /api/errors/6eebe18a0b054de1. Report an issue: GitHub.

Appendix: source

Thrown at internal/editor/editor.go:45

		return errors.Wrap(err, "unable to create temp directory")
	}

	tmpFile := filepath.Join(tmpDir, fname)
	defer os.RemoveAll(tmpDir) //nolint:errcheck

	//nolint:mnd
	if err := os.WriteFile(tmpFile, []byte(initial), 0o600); err != nil {
		return errors.Wrap(err, "unable to write file to edit")
	}

	for {
		if err := EditFile(ctx, tmpFile); err != nil {
			return errors.Wrap(err, "error launching editor")
		}

		txt, err := readAndStripComments(tmpFile, withComments)
		if err != nil {
			return errors.Wrap(err, "error parsing edited file")
		}

		err = parse(txt)
		if err == nil {
			return nil
		}

		log(ctx).Errorf("%v", err)
		fmt.Print("Reopen editor to fix? (Y/n) ")

		var shouldReopen string

		_, _ = fmt.Scanf("%s", &shouldReopen)

		if strings.HasPrefix(strings.ToLower(shouldReopen), "n") {
			return errors.New("aborted")
		}
	}

View on GitHub (pinned to 82495e54b5)