{"record":{"id":"59ffbe120e2901d1","repo":"kubernetes/kops","slug":"renaming-file-q-q-with-q-w","errorCode":null,"errorMessage":"renaming file %q -> %q (with %q): %w","messagePattern":"renaming file %q -> %q \\(with %q\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/vfs/sshfs.go","lineNumber":260,"sourceCode":"\t\t}\n\t\tif err := sftpClient.Rename(tempfile, p.path); err != nil {\n\t\t\treturn fmt.Errorf(\"renaming sftp file %q -> %q (with posix rename): %w\", tempfile, p.path, err)\n\t\t}\n\t\tdeleteTempFile = false\n\t} else {\n\t\tvar session *ssh.Session\n\t\tsession, err = p.client.NewSession()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"creating session for rename: %w\", err)\n\t\t}\n\t\tdefer session.Close()\n\n\t\tcmd := \"mv \" + tempfile + \" \" + p.path\n\t\tif p.sudo {\n\t\t\tcmd = \"sudo \" + cmd\n\t\t}\n\t\tif err := session.Run(cmd); err != nil {\n\t\t\treturn fmt.Errorf(\"renaming file %q -> %q (with %q): %w\", tempfile, p.path, cmd, err)\n\t\t}\n\t\tdeleteTempFile = false\n\t}\n\n\treturn nil\n}\n\n// To prevent concurrent creates on the same file while maintaining atomicity of writes,\n// we take a process-wide lock during the operation.\n// Not a great approach, but fine for a single process (with low concurrency)\nvar createFileLockSSH sync.Mutex\n\nfunc (p *SSHPath) CreateFile(ctx context.Context, data io.ReadSeeker, acl ACL) error {\n\tcreateFileLockSSH.Lock()\n\tdefer createFileLockSSH.Unlock()\n\n\t// Check if exists\n\t_, err := p.ReadFile(ctx)","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/vfs/sshfs.go#L242-L278","documentation":"The non-posix fallback renames the temp file by running a shell command (`mv tempfile p.path`, prefixed with `sudo` if p.sudo is set) through session.Run. If the command exits non-zero, this error wraps the failure and includes the exact command executed. Causes include permission denied, missing mv, or remote disk issues.","triggerScenarios":"session.Run(\"mv ...\") returns non-zero: the SSH user lacks permission on either path (and p.sudo is false so no sudo was used), sudo requires a password/TTY, the shell is restricted, or the target directory vanished.","commonSituations":"Writing to root-owned directories without sudo on the SSHPath; sudoers requiring a TTY (requiretty) or password for the automation user; restricted rbash on bastion hosts; read-only root filesystem.","solutions":["If permission is the issue, construct the SSHPath with sudo enabled: vfs.NewSSHPath(client, server, path, true), and ensure the user has passwordless sudo for mv (NOPASSWD in sudoers).","Remove 'requiretty' and any password prompt for the automation user in /etc/sudoers so non-interactive `sudo mv` works.","Manually test the exact command from the error message via SSH to see the underlying output.","Verify `mv` exists in the default PATH for non-interactive sessions; use an absolute path (/bin/mv) if the PATH is minimal."],"exampleFix":"// before: sudoers prompts for password, session.Run fails\nsftpuser ALL=(ALL) ALL\n// after\nsftpuser ALL=(ALL) NOPASSWD: /bin/mv","handlingStrategy":"validation","validationCode":"// confirm passwordless sudo mv works non-interactively before relying on it\nout := sshRun(host, \"sudo -n true && echo sudo-ok\")\n// require \"sudo-ok\"","typeGuard":null,"tryCatchPattern":"err := path.WriteFile(ctx, data, acl)\nif err != nil && strings.Contains(err.Error(), \"renaming file\") {\n    return fmt.Errorf(\"remote mv failed; run the quoted command manually via ssh to see the real output: %w\", err)\n}","preventionTips":["Grant the automation user NOPASSWD sudo limited to /bin/mv (or required paths).","Remove Defaults requiretty from sudoers for non-interactive automation.","Prefer the posix-rename path (default) to avoid shell/sudo entirely.","Test the exact mv command quoted in the error over an interactive SSH session."],"tags":["ssh","rename","sudo","permissions"],"backgroundTag":"ssh-remote-command-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}