apache/maven · error · IllegalArgumentException

writer, outputStream or path must be non null

Error message

writer, outputStream or path must be non null

What it means

Thrown by DefaultPluginXmlFactory.write(XmlWriterRequest<PluginDescriptor>) when the request has no output target: writer, outputStream and path are all null. The factory refuses the call before any serialization starts. Caller-contract violation, not environmental.

Source

Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultPluginXmlFactory.java:89

            } else {
                try (InputStream is = url.openStream()) {
                    return xml.read(is, request.isStrict());
                }
            }
        } catch (Exception e) {
            throw new XmlReaderException("Unable to read plugin: " + getMessage(e), getLocation(e), e);
        }
    }

    @Override
    public void write(XmlWriterRequest<PluginDescriptor> request) throws XmlWriterException {
        requireNonNull(request, "request");
        PluginDescriptor content = requireNonNull(request.getContent(), "content");
        Path path = request.getPath();
        OutputStream outputStream = request.getOutputStream();
        Writer writer = request.getWriter();
        if (writer == null && outputStream == null && path == null) {
            throw new IllegalArgumentException("writer, outputStream or path must be non null");
        }
        try {
            if (writer != null) {
                new PluginDescriptorStaxWriter().write(writer, content);
            } else if (outputStream != null) {
                new PluginDescriptorStaxWriter().write(outputStream, content);
            } else {
                try (OutputStream os = Files.newOutputStream(path)) {
                    new PluginDescriptorStaxWriter().write(os, content);
                }
            }
        } catch (Exception e) {
            throw new XmlWriterException("Unable to write plugin: " + getMessage(e), getLocation(e), e);
        }
    }

    /**
     * Simply parse the given xml string.

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Set one of .writer(...), .outputStream(...) or .path(...) on the request
  2. In tests, use .writer(new StringWriter()) for in-memory output
  3. Assert the target is present before the call so failures surface in your own terms

Example fix

// before
pluginXmlFactory.write(XmlWriterRequest.builder()
    .content(descriptor)
    .build()); // throws: no output target

// after
StringWriter sw = new StringWriter();
pluginXmlFactory.write(XmlWriterRequest.builder()
    .content(descriptor)
    .writer(sw)
    .build());
Defensive patterns

Strategy: validation

Validate before calling

XmlWriterRequest<PluginDescriptor> req = XmlWriterRequest.builder()
    .content(descriptor)
    .build();
if (req.getWriter() == null && req.getOutputStream() == null && req.getPath() == null) {
    throw new IllegalStateException("descriptor write request has no output target");
}
pluginXmlFactory.write(req);

Prevention

When it happens

Trigger: Calling PluginXmlFactory.write with a request built without .writer(...), .outputStream(...) or .path(...).

Common situations: Round-tripping a descriptor (read then write) where the write request is assembled separately and the target is forgotten; tests that set only the content for in-memory writes.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/0a55816d36a104ad. Report an issue: GitHub.