{"record":{"id":"ba233191eb5eff76","repo":"github/copilot-sdk","slug":"failed-to-chmod-binary-w","errorCode":null,"errorMessage":"failed to chmod binary: %w","messagePattern":"failed to chmod binary: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/cmd/bundler/main.go","lineNumber":1060,"sourceCode":"\twrapperName := runtimeWrapperName(binaryName)\n\tif err := extractFileFromTarball(\n\t\ttarballPath,\n\t\tdestDir,\n\t\t\"package/prebuilds/\"+runtimePlatform+\"/\"+wrapperName,\n\t\tbinaryName,\n\t); err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to extract runtime wrapper compatibility entrypoint: %w\", err)\n\t}\n\n\t// Verify binary exists\n\tif _, err := os.Stat(binaryPath); err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"binary not found after extraction: %w\", err)\n\t}\n\n\t// Make executable on Unix\n\tif !strings.HasSuffix(binaryName, \".exe\") {\n\t\tif err := os.Chmod(binaryPath, 0755); err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"failed to chmod binary: %w\", err)\n\t\t}\n\t}\n\n\tstat, err := os.Stat(binaryPath)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to stat binary: %w\", err)\n\t}\n\tsizeMB := float64(stat.Size()) / 1024 / 1024\n\tfmt.Printf(\"Downloaded %s (%.1f MB)\\n\", binaryName, sizeMB)\n\n\treturn binaryPath, tarballPath, nil\n}\n\n// extractCLILicense writes the license from the verified release package next to outputPath.\nfunc extractCLILicense(tarballPath, outputPath string) error {\n\toutputDir := filepath.Dir(outputPath)\n\tif outputDir == \"\" {\n\t\toutputDir = \".\"","sourceCodeStart":1042,"sourceCodeEnd":1078,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/cmd/bundler/main.go#L1042-L1078","documentation":"On non-Windows targets (binary name not ending in .exe), the bundler chmods the extracted binary to 0755 so it is executable. If os.Chmod fails, this error wraps the failure. The binary exists but cannot yet be marked executable.","triggerScenarios":"os.Chmod(binaryPath, 0755) returns non-nil — read-only filesystem, ownership mismatch, or immutable/ACL-restricted destination file.","commonSituations":"destDir on a mounted volume with noexec/no-permission changes (some Windows mounts, FAT/exFAT, container read-only layer); file owned by another user after a sudo-run previous build.","solutions":["Ensure the destination filesystem supports POSIX permission changes (avoid FAT/exFAT/overlay mounts).","Fix ownership of the extracted file (sudo chown) or clean stale build dirs from prior privileged runs.","Run the build as a user with write permission on destDir.","Move TMPDIR/destDir to a normal local ext4/APFS filesystem."],"exampleFix":"// before: destDir inside a read-only container layer\n// after: use a writable location\ndestDir = filepath.Join(os.TempDir(), \"bundler-cli\")","handlingStrategy":"validation","validationCode":"// verify permission changes are possible on destDir\nprobe := filepath.Join(destDir, \".chmod-probe\")\nos.WriteFile(probe, nil, 0o644)\nif err := os.Chmod(probe, 0o755); err != nil {\n    return fmt.Errorf(\"filesystem %s does not support chmod: %w\", destDir, err)\n}\nos.Remove(probe)","typeGuard":null,"tryCatchPattern":"if err := buildBundle(...); err != nil {\n    if strings.Contains(err.Error(), \"failed to chmod binary\") {\n        moveDestToLocalFS(); retry()\n    }\n    return err\n}","preventionTips":["Build on POSIX filesystems (ext4/APFS) rather than FAT/exFAT/network mounts.","Run builds as a user owning the output directory.","Clean up artifacts from previous sudo runs to avoid ownership conflicts.","Point TMPDIR at a writable local path."],"tags":["permissions","chmod","filesystem","go"],"backgroundTag":"permission-denied","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}