{"record":{"id":"de556dbf9b97380f","repo":"apache/maven","slug":"unable-to-write-toolchains","errorCode":null,"errorMessage":"Unable to write toolchains: {}","messagePattern":"Unable to write toolchains: (.+?)","errorType":"exception","errorClass":"XmlWriterException","httpStatus":null,"severity":"error","filePath":"impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultToolchainsXmlFactory.java","lineNumber":102,"sourceCode":"        }\n        try {\n            MavenToolchainsStaxWriter xmlWriter = new MavenToolchainsStaxWriter();\n            xmlWriter.setAddLocationInformation(false);\n\n            Function<Object, String> formatter = request.getInputLocationFormatter();\n            if (formatter != null) {\n                xmlWriter.setAddLocationInformation(true);\n                Function<InputLocation, String> adapter = formatter::apply;\n                xmlWriter.setStringFormatter(adapter);\n            }\n\n            if (writer != null) {\n                xmlWriter.write(writer, content);\n            } else {\n                xmlWriter.write(outputStream, content);\n            }\n        } catch (Exception e) {\n            throw new XmlWriterException(\"Unable to write toolchains: \" + getMessage(e), getLocation(e), e);\n        }\n    }\n}\n","sourceCodeStart":84,"sourceCodeEnd":106,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultToolchainsXmlFactory.java#L84-L106","documentation":"Thrown by ToolchainsXmlFactory.write (DefaultToolchainsXmlFactory) when serializing a PersistedToolchains model to XML fails. The method wraps every exception raised by the StAX writer while writing to the supplied Writer/OutputStream, and appends the underlying cause's message to 'Unable to write toolchains: '. Typical root causes are I/O failures (read-only or missing output path, closed stream, disk full) or a model containing values the toolchains writer cannot serialize.","triggerScenarios":"Calling ToolchainsXmlFactory.write(XmlWriterRequest) with an OutputStream/Writer that is closed or targets a read-only file; passing a hand-built PersistedToolchains whose toolchain entries contain null type or null parameters; disk exhaustion during the write.","commonSituations":"Programmatic editing of ~/.m2/toolchains.xml through the Maven API where the model was assembled manually instead of round-tripped; CI agents with full disks; writing to a directory the process does not own; a partially-populated model after a failed read-modify-write cycle.","solutions":["Read the appended cause message and inspect XmlWriterException.getCause() to distinguish IOException (output target problem) from a model/serialization problem","Verify the output file is writable and the stream/writer is still open before calling write","Round-trip the model: read toolchains with the same factory, modify the result, and write it back instead of constructing PersistedToolchains by hand","Ensure every Toolchain entry has a non-null type and a non-null parameters map before writing"],"exampleFix":"// before: hand-built model, closed stream\nPersistedToolchains tc = new PersistedToolchains();\ntc.addToolchain(new Toolchain(null, null)); // null type\nfactory.write(XmlWriterRequest.builder().content(tc).outputStream(closedOut).build());\n\n// after: round-trip a valid model to a writable target\nPersistedToolchains tc = factory.read(XmlReaderRequest.builder().path(toolchainsPath).build());\ntc.getToolchains().get(0).getParameters().put(\"jdk\", \"17\");\ntry (OutputStream out = Files.newOutputStream(toolchainsPath)) {\n    factory.write(XmlWriterRequest.builder().content(tc).outputStream(out).build());\n}","handlingStrategy":"try-catch","validationCode":"// before writing toolchains\nPath out = toolchainsPath;\nif (!Files.isWritable(out.getParent() == null ? Path.of(\".\") : out.getParent())) {\n    throw new IllegalStateException(\"toolchains output directory not writable: \" + out);\n}\nfor (Toolchain tc : content.getToolchains()) {\n    Objects.requireNonNull(tc.getType(), \"toolchain type\");\n    Objects.requireNonNull(tc.getParameters(), \"toolchain parameters\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    toolchainsXmlFactory.write(request);\n} catch (XmlWriterException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof IOException io) {\n        // output target problem: permissions, closed stream, disk full\n        throw new IllegalStateException(\"Cannot write toolchains to target: \" + io.getMessage(), e);\n    }\n    throw e; // model/serialization problem: fix the content\n}","preventionTips":["Round-trip toolchains.xml with the same factory (read, modify, write) instead of hand-building PersistedToolchains","Keep the output stream open and owned by the write call; do not reuse streams from prior operations","Validate that every Toolchain has a non-null type and parameters map before writing"],"tags":["maven","toolchains","xml","serialization","io"],"backgroundTag":"xml-serialization-failed","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}