{"record":{"id":"56acee57c43bfa00","repo":"quarkusio/quarkus","slug":"failed-to-set-file-script-executable-protoc-i","errorCode":null,"errorMessage":"failed to set file: ${script} executable. Protoc invocation may fail","messagePattern":"failed to set file: (.+?) executable\\. Protoc invocation may fail","errorType":"exception","errorClass":"CodeGenFailureException","httpStatus":null,"severity":"error","filePath":"extensions/grpc/codegen/src/main/java/io/quarkus/grpc/codegen/GrpcCodeGen.java","lineNumber":599,"sourceCode":"            return writeScript(buildDir, pluginPath, \"#!/bin/sh\\n\", \".sh\");\n        } else {\n            return writeScript(buildDir, pluginPath, \"@echo off\\r\\n\", \".cmd\");\n        }\n    }\n\n    private static Path writeScript(Path buildDir, Path pluginPath, String shebang, String suffix) throws CodeGenException {\n        Path script;\n        try {\n            script = Files.createTempFile(buildDir, \"quarkus-grpc\", suffix);\n            try (BufferedWriter writer = Files.newBufferedWriter(script)) {\n                writer.write(shebang);\n                writePluginExeCmd(pluginPath, writer);\n            }\n        } catch (IOException e) {\n            throw new CodeGenException(\"Failed to create a wrapper script for quarkus-grpc plugin\", e);\n        }\n        if (!script.toFile().setExecutable(true)) {\n            throw new CodeGenFailureException(\"failed to set file: \" + script + \" executable. Protoc invocation may fail\");\n        }\n        return script;\n    }\n\n    private static void writePluginExeCmd(Path pluginPath, BufferedWriter writer) throws IOException {\n        writer.write(\"\\\"\" + io.smallrye.common.process.ProcessUtil.pathOfJava().toString() + \"\\\" -cp \\\"\" +\n                pluginPath.toAbsolutePath() + \"\\\" \" + quarkusProtocPluginMain);\n        writer.newLine();\n    }\n\n    private static boolean containsQuarkusKotlin(Collection<ResolvedDependency> dependencies) {\n        return dependencies.stream().anyMatch(new Predicate<ResolvedDependency>() {\n            @Override\n            public boolean test(ResolvedDependency rd) {\n                return rd.getGroupId().equalsIgnoreCase(\"io.quarkus\")\n                        && rd.getArtifactId().equalsIgnoreCase(\"quarkus-kotlin\");\n            }\n        });","sourceCodeStart":581,"sourceCodeEnd":617,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/codegen/GrpcCodeGen.java#L581-L617","documentation":"After writing the quarkus-grpc wrapper script, writeScript calls File.setExecutable(true); if the OS cannot set the execute bit it throws GrpcCodeGenFailureException with this message, warning that the subsequent protoc invocation will likely fail. Note it is a GrpcCodeGenFailureException, not CodeGenException.","triggerScenarios":"Code generation where the newly created .sh/.cmd wrapper script lives on a filesystem that rejects execute permissions — noexec mounts, NTFS/FAT via WSL /mnt/c, NFS/SMB shares, Windows FAT-formatted drives.","commonSituations":"noexec Docker volume mounts for the build directory; WSL working on /mnt/c; network home directories (NFS with root_squash/noexec); CI tmpfs with noexec.","solutions":["Move the build to a filesystem supporting execute bits (Linux ext4/overlayfs, WSL native home dir instead of /mnt/c)","Remount the volume without noexec (mount -o remount,exec or drop noexec from fstab/docker volume options)","Run the build inside a container with exec permissions on the workspace mount","If on Windows, confirm the failure is benign for .cmd files — but prefer building in a Linux container to avoid it"],"exampleFix":"# before\ndocker run -v $(pwd):/project:noexec quarkus-build\n# after\ndocker run -v $(pwd):/project quarkus-build","handlingStrategy":"validation","validationCode":"// probe exec-bit support in the build directory before codegen\nPath probe = buildDir.resolve(\".exec-probe.sh\");\nFiles.writeString(probe, \"#!/bin/sh\\n\");\nif (!probe.toFile().setExecutable(true)) {\n    throw new IllegalStateException(\"Cannot set exec bit on \" + buildDir + \" — noexec mount? Move the build directory.\");\n}\nFiles.deleteIfExists(probe);","typeGuard":null,"tryCatchPattern":"try {\n    build.run();\n} catch (GrpcCodeGenFailureException e) {\n    if (e.getMessage().contains(\"failed to set file\")) {\n        throw new IllegalStateException(\"Build dir lacks exec permission support; remount without noexec or move workspace\", e);\n    }\n}","preventionTips":["Avoid mounting build workspaces with :noexec in Docker or fstab","In WSL, keep projects under the Linux filesystem (~/...), not /mnt/c","Check NFS/SMB mount options (noexec, root_squash) before CI setup","Prefer building in a standard Linux container with exec-capable overlayfs"],"tags":["filesystem","permissions","grpc","codegen"],"backgroundTag":"permission-denied","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}