googleapis/mcp-toolbox · error
failed to rename file: %w
Error message
failed to rename file: %w
What it means
Thrown when runMigrate cannot rename the original file to `<filePath>.bak` via `os.Rename` before writing the migrated content. The backup rename is part of a safe write sequence (backup, write, restore on failure); if it fails the file is left untouched and the error (with the wrapped OS reason) is appended to errs and that file is skipped. Typical underlying errors are EACCES/EPERM (no write permission on the directory) or EXDEV (source and destination on different filesystems, which cannot happen here since only `.bak` is appended, so permission/locking issues dominate).
Source
Thrown at cmd/internal/migrate/command.go:103
if cmp.Equal(buf, newBuf) {
continue
}
if cmd.dryRun {
logger.DebugContext(ctx, fmt.Sprintf("printing migration to output for file: %s", filePath))
fmt.Fprintln(opts.IOStreams.Out, string(newBuf))
} else {
info, err := os.Stat(filePath)
if err != nil {
errMsg := fmt.Errorf("failed to stat file: %w", err)
logger.ErrorContext(ctx, errMsg.Error())
errs = append(errs, errMsg)
continue
}
backupFile := filePath + ".bak"
err = os.Rename(filePath, backupFile)
if err != nil {
errMsg := fmt.Errorf("failed to rename file: %w", err)
logger.ErrorContext(ctx, errMsg.Error())
errs = append(errs, errMsg)
continue
}
logger.DebugContext(ctx, fmt.Sprintf("successfully renamed %s to %s", filePath, backupFile))
// set the permission to the original file's permission.
err = os.WriteFile(filePath, newBuf, info.Mode().Perm())
if err != nil {
errMsg := fmt.Errorf("failed to write to file: %w", err)
// restoring original file
if removeErr := os.Remove(filePath); removeErr != nil { // Attempt to remove the possibly partial file to ensure Rename succeeds.
errMsg = errors.Join(errMsg, removeErr)
}
if restoreErr := os.Rename(backupFile, filePath); restoreErr != nil {
fullRestoreErr := fmt.Errorf("failed to restore original file: %w", restoreErr)
errMsg = errors.Join(errMsg, fullRestoreErr)
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Check directory write permission: `ls -ld <dir>`; run migrate as a user with write access or fix ownership with chown/chmod.
- Verify the volume is not mounted read-only (`mount | grep <dir>`) and remount read-write.
- Look for a stale `filePath.bak` and remove it, then re-run migrate.
- Close any process holding locks on the file (editors, antivirus, other containers) and retry.
- Ensure the filesystem is not full: `df -h <dir>`.
Defensive patterns
Strategy: validation
Validate before calling
dir := filepath.Dir(filePath)
probe := filepath.Join(dir, ".migrate_probe")
if err := os.WriteFile(probe, nil, 0o600); err != nil {
return fmt.Errorf("directory %s is not writable: %v", dir, err)
}
os.Remove(probe) Prevention
- Confirm the target directory is on a read-write mount before running inside containers.
- Remove stale `.bak` files left by aborted runs before migrating.
- Run migrate outside editors/AV scanners that may lock files, or exclude the workspace from AV.
- Check `df -h` for a full filesystem before bulk migrations.
When it happens
Trigger: The directory containing the file is not writable by the current user, the file is immutable (chattr +i) or held by another process that blocks rename (rare on Linux, common on Windows file locks), or the filesystem is full/read-only.
Common situations: Running migrate inside a Docker container whose mounted volume is read-only; editing files owned by another user without sudo; a leftover `.bak` from a previous crashed run combined with odd directory ACLs; antivirus or editor locking the file on Windows/macOS; disk mounted read-only after filesystem errors.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- failed to stat file: %w
- failed to write to file: %w
- failed to restore original file: %w
- error writing script %s: %w
- error writing SKILL.md: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/e4dbfbeddd74d172.
Report an issue: GitHub.