{"record":{"id":"5be13388dc0223c3","repo":"googleapis/mcp-toolbox","slug":"failed-to-restore-original-file-w","errorCode":null,"errorMessage":"failed to restore original file: %w","messagePattern":"failed to restore original file: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cmd/internal/migrate/command.go","lineNumber":119,"sourceCode":"\t\t\terr = os.Rename(filePath, backupFile)\n\t\t\tif err != nil {\n\t\t\t\terrMsg := fmt.Errorf(\"failed to rename file: %w\", err)\n\t\t\t\tlogger.ErrorContext(ctx, errMsg.Error())\n\t\t\t\terrs = append(errs, errMsg)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlogger.DebugContext(ctx, fmt.Sprintf(\"successfully renamed %s to %s\", filePath, backupFile))\n\n\t\t\t// set the permission to the original file's permission.\n\t\t\terr = os.WriteFile(filePath, newBuf, info.Mode().Perm())\n\t\t\tif err != nil {\n\t\t\t\terrMsg := fmt.Errorf(\"failed to write to file: %w\", err)\n\t\t\t\t// restoring original file\n\t\t\t\tif removeErr := os.Remove(filePath); removeErr != nil { // Attempt to remove the possibly partial file to ensure Rename succeeds.\n\t\t\t\t\terrMsg = errors.Join(errMsg, removeErr)\n\t\t\t\t}\n\t\t\t\tif restoreErr := os.Rename(backupFile, filePath); restoreErr != nil {\n\t\t\t\t\tfullRestoreErr := fmt.Errorf(\"failed to restore original file: %w\", restoreErr)\n\t\t\t\t\terrMsg = errors.Join(errMsg, fullRestoreErr)\n\t\t\t\t}\n\t\t\t\tlogger.ErrorContext(ctx, errMsg.Error())\n\t\t\t\terrs = append(errs, errMsg)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlogger.DebugContext(ctx, fmt.Sprintf(\"migration completed for file: %s\", filePath))\n\t\t}\n\t}\n\n\tlogger.InfoContext(ctx, \"migration ended!\")\n\t// If errs is empty, errors.Join returns nil\n\treturn errors.Join(errs...)\n}\n","sourceCodeStart":101,"sourceCodeEnd":134,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/cmd/internal/migrate/command.go#L101-L134","documentation":"This is the secondary error raised when BOTH the write of migrated content failed (error 47) AND the automatic restore (`os.Rename(backupFile, filePath)`) also failed. It is joined with the write error via `errors.Join`, so the reported message contains the original write failure plus 'failed to restore original file'. At this point the original content lives only in `<filePath>.bak` and the target path may be missing or hold a partial file, making this the most dangerous state the migrate command can produce.","triggerScenarios":"After a failed os.WriteFile, the cleanup os.Remove(filePath) or the restore os.Rename(backupFile, filePath) fails — e.g. the directory became non-writable, the .bak was concurrently deleted, or the .bak itself sits on a failing filesystem. Any condition causing the initial failure usually also causes the restore to fail.","commonSituations":"Disk full: both write and restore fail; the file is left missing with only `file.bak` present. Container volume switched to read-only mid-run. Another process (or a previous crashed run) already removed the .bak. NFS stale-handle errors after the server restarted.","solutions":["Immediately recover manually: `mv <filePath>.bak <filePath>` — the original content is in the .bak.","If `.bak` is missing, restore the file from version control or backups; never leave a partial file in place.","Fix the root environmental cause (free disk space, remount read-write, fix permissions) before re-running migrate.","Avoid concurrent processes touching the same paths during migrate (lock or stop other tooling).","Re-run migrate and confirm the error list is empty."],"exampleFix":"// before: assuming .bak always exists\n// after: verify and restore defensively before re-running\nif _, err := os.Stat(\"config.yaml.bak\"); err == nil {\n    if err := os.Rename(\"config.yaml.bak\", \"config.yaml\"); err != nil {\n        log.Fatalf(\"manual restore failed: %v\", err)\n    }\n}","handlingStrategy":"fallback","validationCode":"before, err := os.ReadFile(filePath)\nif err != nil { return err }\nif err := os.WriteFile(filePath+\".pre-migrate-copy\", before, 0o600); err != nil {\n    return fmt.Errorf(\"cannot create safety copy: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil || failed {\n        if _, err := os.Stat(path + \".bak\"); err == nil {\n            _ = os.Remove(path)            // drop partial file\n            if rErr := os.Rename(path+\".bak\", path); rErr != nil {\n                log.Fatalf(\"CRITICAL: could not restore %s from .bak: %v\", path, rErr)\n            }\n        }\n    }\n}()","preventionTips":["Make an explicit copy of the file before any migrate run on important paths.","Never delete `file.bak` until the migrated file has been verified (build/test passes).","Keep migrate targets on a healthy local filesystem; avoid NFS and read-only mounts.","Do not run migrate concurrently with other tooling touching the same files.","If you see the joined restore error, treat data as at-risk and restore from VCS/backup first."],"tags":["go","filesystem","migrate","data-loss","restore-failed"],"backgroundTag":"file-restore-failed","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}