{"record":{"id":"c85279018b565dbb","repo":"quarkusio/quarkus","slug":"failed-to-persist-extension-descriptor","errorCode":null,"errorMessage":"Failed to persist extension descriptor ","messagePattern":"Failed to persist extension descriptor ","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTask.java","lineNumber":314,"sourceCode":"                        final String resource = resources.get(i);\n                        if (!resource.isBlank()) {\n                            sb.append(',').append(resource);\n                        }\n                    }\n                    value = sb.toString();\n                }\n                props.setProperty(ApplicationModelBuilder.REMOVED_RESOURCES_DOT + key, value);\n            }\n        }\n\n        try {\n            Files.createDirectories(metaInfDir);\n            try (BufferedWriter writer = Files\n                    .newBufferedWriter(metaInfDir.resolve(BootstrapConstants.DESCRIPTOR_FILE_NAME))) {\n                props.store(writer, \"Generated by extension-descriptor\");\n            }\n        } catch (IOException e) {\n            throw new GradleException(\n                    \"Failed to persist extension descriptor \" + metaInfDir.resolve(BootstrapConstants.DESCRIPTOR_FILE_NAME),\n                    e);\n        }\n    }\n\n    private static void setConditionalDepsProperty(String propName, List<String> conditionalDependencies, Properties props) {\n        if (conditionalDependencies != null && !conditionalDependencies.isEmpty()) {\n            final StringBuilder buf = new StringBuilder();\n            int i = 0;\n            buf.append(ArtifactCoords.fromString(conditionalDependencies.get(i++)));\n            while (i < conditionalDependencies.size()) {\n                buf.append(' ').append(ArtifactCoords.fromString(conditionalDependencies.get(i++)));\n            }\n            props.setProperty(propName, buf.toString());\n        }\n    }\n\n    private void generateQuarkusExtensionDescriptor(Path outputMetaInfDirectory)","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTask.java#L296-L332","documentation":"Thrown by ExtensionDescriptorTask.generateQuarkusExtensionProperties when writing quarkus-extension.properties into META-INF fails with an IOException. The task creates the META-INF directory and stores the resolved Properties object via a BufferedWriter; any I/O problem (missing dir creation, read-only target, closed stream) is wrapped in this GradleException naming the target file.","triggerScenarios":"Files.createDirectories or props.store(writer, ...) throws — e.g. metaInfDir cannot be created under a read-only output directory, the descriptor file is locked by another process, or the disk is full.","commonSituations":"CI workspaces with the output directory mounted read-only, concurrent tasks writing the same output dir, permission mismatches from switching build users, or full disks.","solutions":["Ensure the task's output directory is writable and not read-only mounted; fix permissions with chmod/chown.","Run gradle clean to remove a partially generated META-INF, then rebuild.","Check disk space and close other processes (IDE sync, previous daemon) holding the descriptor file open.","Run the task alone (avoid concurrent builds writing to the same directory)."],"exampleFix":"// before: read-only output dir\nextensionDescriptor { outputDirectory = file('/mnt/ro/target/classes') }\n// after: point at a writable dir\nextensionDescriptor { outputDirectory = file(\"${buildDir}/classes/java/main\") }/","handlingStrategy":"try-catch","validationCode":"def out = project.file('build/classes/java/main/META-INF')\nif (out.exists() && !out.canWrite()) throw new IllegalStateException(\"META-INF dir not writable: $out\")\nif (out.totalSpace > 0 && out.usableSpace < 10L * 1024 * 1024) throw new IllegalStateException('Disk nearly full')","typeGuard":null,"tryCatchPattern":"try {\n  generateQuarkusExtensionProperties()\n} catch (GradleException e) {\n  def target = e.message.minus('Failed to persist extension descriptor ')\n  new File(target).delete()\n  generateQuarkusExtensionProperties() // retry once after removing stale/locked file\n}","preventionTips":["Run builds as a single consistent OS user.","Exclude build outputs from AV/indexers that lock files.","Free disk space before large extension builds in CI.","Avoid concurrent Gradle builds on the same project directory."],"tags":["gradle","ioexception","descriptor","filesystem"],"backgroundTag":"file-write-failed","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"}