{"record":{"id":"149b236e37f63bce","repo":"Hmbown/CodeWhale","slug":"staged-update-is-not-executable-mode-03o-refusing-to-replace","errorCode":null,"errorMessage":"staged update {} is not executable (mode {:03o}); refusing to replace {}","messagePattern":"staged update (.+?) is not executable \\(mode (.+?)\\); refusing to replace (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/update.rs","lineNumber":1893,"sourceCode":"    // Independently verify the staged binary is executable before it may\n    // replace the target; a chmod that silently did not stick would otherwise\n    // install a binary that cannot run.\n    #[cfg(unix)]\n    {\n        use std::os::unix::fs::PermissionsExt;\n        let staged_mode = tmp\n            .as_file()\n            .metadata()\n            .with_context(|| {\n                format!(\n                    \"failed to inspect staged update at {}\",\n                    tmp.path().display()\n                )\n            })?\n            .permissions()\n            .mode();\n        if staged_mode & 0o111 == 0 {\n            bail!(\n                \"staged update {} is not executable (mode {:03o}); refusing to replace {}\",\n                tmp.path().display(),\n                staged_mode & 0o7777,\n                target.display()\n            );\n        }\n    }\n\n    validate_before_replace()?;\n\n    #[cfg(windows)]\n    {\n        let backup = backup_path_for(target);\n        if target.exists() {\n            std::fs::rename(target, &backup).with_context(|| {\n                format!(\n                    \"failed to move current executable {} to {}\",\n                    target.display(),","sourceCodeStart":1875,"sourceCodeEnd":1911,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/update.rs#L1875-L1911","documentation":"Thrown during the atomic install step of self-update. After staging the new binary to a temp file, the updater checks that the staged file has any execute permission bit (0o111); if not (mode bits shown in octal), it refuses to replace the current binary rather than installing an unrunnable executable.","triggerScenarios":"Self-update reaches the persist step but the extracted/staged temp binary lacks execute bits — typically when the archive stored the file mode 0644 or the extraction lost permissions.","commonSituations":"Extraction tool or code copied the file without preserving the mode bit; extracting on a filesystem that does not support Unix permissions; a packaging bug in the release archive.","solutions":["Re-run the update so the staged binary is written with mode 0755 (set executable bits on extraction).","Fix the extraction code to apply Unix permissions from the archive entries.","Check the release archive: confirm the binary entry has executable permissions and rebuild it if not.","Ensure the target filesystem supports execute permissions (not mounted noexec)."],"exampleFix":"// before\nfs::write(&staged_path, bytes)?;\n// after\nfs::write(&staged_path, bytes)?;\nlet mut perms = fs::metadata(&staged_path)?.permissions();\nuse std::os::unix::fs::PermissionsExt;\nperms.set_mode(0o755);\nfs::set_permissions(&staged_path, perms)?;","handlingStrategy":"validation","validationCode":"use std::os::unix::fs::PermissionsExt;\nlet mode = std::fs::metadata(&staged)?.permissions().mode();\nif mode & 0o111 == 0 {\n    eprintln!(\"staged binary {staged:?} not executable (mode {mode:03o}); fix extraction or mount\", );\n    return Err(anyhow!(\"staged binary not executable\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set mode 0755 on the staged binary right after extraction.","Preserve Unix permission bits when unpacking archives (use a tar/zip lib that reads external attributes).","Ensure the target filesystem is not mounted noexec.","Test the update path on each OS you ship."],"tags":["update","permissions","filesystem"],"backgroundTag":"permission-denied","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}