{"record":{"id":"43b199e5d1811814","repo":"github/copilot-sdk","slug":"failed-to-make-copilot-cli-executable","errorCode":null,"errorMessage":"Failed to make Copilot CLI executable: ","messagePattern":"Failed to make Copilot CLI executable: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java","lineNumber":574,"sourceCode":"        if (!Files.isRegularFile(path)) {\n            return false;\n        }\n        return Files.size(path) > 0;\n    }\n\n    private static boolean isValidCachedCli(Path path) throws IOException {\n        return isValidCachedFile(path) && (isWindows() || Files.isExecutable(path));\n    }\n\n    private static void makeExecutable(Path path) throws IOException {\n        if (isWindows()) {\n            return;\n        }\n        final boolean executableSet;\n        try {\n            executableSet = path.toFile().setExecutable(true, false);\n        } catch (SecurityException ex) {\n            throw new IOException(\"Failed to make Copilot CLI executable: \" + path, ex);\n        }\n        if (!executableSet || !Files.isExecutable(path)) {\n            throw new IOException(\"Failed to make Copilot CLI executable: \" + path);\n        }\n    }\n\n    private static void copyResourceToTemp(URL resource, String resourcePath, Path temp) throws IOException {\n        try (InputStream in = resource.openStream()) {\n            long bytesWritten = Files.copy(in, temp, StandardCopyOption.REPLACE_EXISTING);\n            if (bytesWritten == 0) {\n                throw new IllegalStateException(\"Classpath resource is empty: \" + resourcePath);\n            }\n        }\n        // Flush OS buffers to durable storage before the atomic rename.\n        try (FileChannel channel = FileChannel.open(temp, StandardOpenOption.WRITE)) {\n            channel.force(true);\n        }\n    }","sourceCodeStart":556,"sourceCodeEnd":592,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java#L556-L592","documentation":"makeExecutable calls File.setExecutable(true, false) on a freshly written binary. If a SecurityException is raised, this IOException wrapping the path is thrown. It means the JVM was not permitted to set the executable bit — typically a Java SecurityManager policy restriction or an OS-level ACL denying chmod on the target.","triggerScenarios":"A SecurityManager (or sandboxed embedding) denies FilePermission 'execute'/'write' for the cache path when resolving the runtime wrapper or extracting runtime assets/CLI.","commonSituations":"Application servers or containerized environments running with a SecurityManager and restrictive policy; read-only or ACL-locked cache directories; macOS/Windows ACLs on company-managed machines.","solutions":["Grant the running code FilePermission(read,write,execute) on the cache directory in the security policy.","Point the cache directory at a user-writable location (e.g. -Dcopilot.cache.dir=$HOME/.cache/copilot).","Remove or relax the SecurityManager/sandbox restrictions if policy allows.","Check directory ACLs (icacls / chmod / ls -le) and fix ownership so the running user can chmod files."],"exampleFix":"// before (policy file)\ngrant { permission java.io.FilePermission \"/opt/copilot-cache/-\", \"read\"; };\n// after\ngrant { permission java.io.FilePermission \"/opt/copilot-cache/-\", \"read,write,execute,delete\"; };","handlingStrategy":"try-catch","validationCode":"// Java: confirm the JVM may write+execute in the cache dir before loading\nPath probe = cacheDir.resolve(\".probe\");\nFiles.writeString(probe, \"x\");\nprobe.toFile().setExecutable(true, false);\nFiles.deleteIfExists(probe);","typeGuard":null,"tryCatchPattern":"try { loader.loadRuntime(); } catch (IOException e) { if (e instanceof SecurityException || e.getMessage().startsWith(\"Failed to make Copilot CLI executable\")) { // widen SecurityManager policy or switch cache dir } else throw e; }","preventionTips":["Grant FilePermission read/write/execute/delete on the cache path when using a SecurityManager","Run under a user with write access to the cache directory","Check OS ACLs on company-managed machines before deploying"],"tags":["permissions","security-manager","java","filesystem"],"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"}