wavetermdev/waveterm · error

failed to write file: %w

Error message

failed to write file: %w

What it means

After edits apply successfully in memory, ReplaceInFile writes the result back with os.WriteFile using the file's original mode. A failed write (permissions, read-only fs, disk full) is wrapped with this message; note this path uses a plain in-place write, not the atomic temp-file rename.

Source

Thrown at pkg/util/fileutil/fileutil.go:363

		return fmt.Errorf("not a regular file: %s", filePath)
	}

	if fileInfo.Size() > MaxEditFileSize {
		return fmt.Errorf("file too large for editing: %d bytes (max: %d)", fileInfo.Size(), MaxEditFileSize)
	}

	contents, err := os.ReadFile(filePath)
	if err != nil {
		return fmt.Errorf("failed to read file: %w", err)
	}

	modifiedContents, err := ApplyEdits(contents, edits)
	if err != nil {
		return err
	}

	if err := os.WriteFile(filePath, modifiedContents, fileInfo.Mode()); err != nil {
		return fmt.Errorf("failed to write file: %w", err)
	}

	return nil
}

// ReplaceInFilePartial applies edits incrementally up to the first failure.
// Returns the results for each edit and writes the partially modified content.
func ReplaceInFilePartial(filePath string, edits []EditSpec) ([]EditResult, error) {
	fileInfo, err := os.Stat(filePath)
	if err != nil {
		return nil, fmt.Errorf("failed to stat file: %w", err)
	}

	if !fileInfo.Mode().IsRegular() {
		return nil, fmt.Errorf("not a regular file: %s", filePath)
	}

	if fileInfo.Size() > MaxEditFileSize {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Make the file writable (chmod u+w) or run as a user with write access.
  2. Check disk space and read-only mount status.
  3. Close programs holding a write lock on the file, then retry.
  4. Prefer a write-then-rename flow (e.g. write to a temp file and AtomicWriteFile) if partial writes are a concern.

Example fix

// before
fileutil.ReplaceInFile("settings.json", edits) // mode 0444

// after
os.Chmod(path, 0644) // ensure writable
fileutil.ReplaceInFile(path, edits)
Defensive patterns

Strategy: validation

Validate before calling

// ensure the file is writable with its current mode
fi, err := os.Stat(path)
if err != nil {
    return err
}
if fi.Mode().Perm()&0200 == 0 {
    return fmt.Errorf("%s is read-only (mode %v)", path, fi.Mode())
}

Try / catch

// Go: fix writability, then retry once
if err := fileutil.ReplaceInFile(path, edits); err != nil {
    if strings.Contains(err.Error(), "failed to write file") {
        if cerr := os.Chmod(path, 0644); cerr == nil {
            return fileutil.ReplaceInFile(path, edits)
        }
    }
    return err
}

Prevention

When it happens

Trigger: os.WriteFile(filePath, modifiedContents, fileInfo.Mode()) failing: read-only file mode, directory lacking write permission, disk full, or immutable file attribute.

Common situations: Editing a checked-in file made read-only (chmod 444, or read-only from version-control state); full disk; editing files on a read-only mount; Windows file locked by another process.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/1b4c7ad897743f00. Report an issue: GitHub.