quarkusio/quarkus · error · IllegalArgumentException

${coords} does not follow format <groupId>:<artifactId>[:<cl

Error message

${coords} does not follow format <groupId>:<artifactId>[:<classifier>[:<type>]]

What it means

The GACT constructor parses a colon-separated coordinate string into groupId/artifactId/classifier/type (+version) and throws IllegalArgumentException when the string does not match <groupId>:<artifactId>[:<classifier>[:<type>]] shape. The message includes the offending input after the appended text.

Source

Thrown at independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACT.java:43

    protected final String classifier;
    protected final String type;

    public GACT(String[] parts) {
        if (parts == null || parts.length < 2 || parts.length > 4) {
            final StringBuilder sb = new StringBuilder().append("Artifact key ");
            if (parts == null) {
                sb.append("null");
            } else {
                sb.append('\'');
                if (parts.length > 0) {
                    sb.append(parts[0]);
                    for (int i = 1; i < parts.length; ++i) {
                        sb.append(':').append(parts[i]);
                    }
                }
                sb.append('\'');
            }
            throw new IllegalArgumentException(
                    sb.append(" does not follow format <groupId>:<artifactId>[:<classifier>[:<type>]]").toString());
        }
        this.groupId = parts[0];
        this.artifactId = parts[1];
        if (parts.length == 2 || parts[2] == null) {
            this.classifier = ArtifactCoords.DEFAULT_CLASSIFIER;
        } else {
            this.classifier = parts[2];
        }
        if (parts.length <= 3 || parts[3] == null) {
            this.type = ArtifactCoords.TYPE_JAR;
        } else {
            this.type = parts[3];
        }
    }

    public GACT(String groupId, String artifactId) {
        this(groupId, artifactId, null);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Provide coordinates in groupId:artifactId[:classifier][:type] form with non-empty groupId and artifactId
  2. Remove version segments if the target API is GACT-only (version is handled by ArtifactCoords.split)
  3. Resolve ${...} placeholders so no segment is empty
  4. Pre-validate by splitting on ':' and checking the first two segments are non-empty

Example fix

// before
new GACT("com.acme::jar", null); // throws
// after
new GACT("com.acme:app:jar", null);
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidGact(String s) {
    String[] p = s == null ? new String[0] : s.split(":", -1);
    return p.length >= 2 && p.length <= 4 && !p[0].isEmpty() && !p[1].isEmpty();
}

Try / catch

try {
    ArtifactCoords c = new GACT(str, null);
} catch (IllegalArgumentException e) {
    log.error("Bad coordinates, expected G:A[:C[:T]]: " + str);
}

Prevention

When it happens

Trigger: Constructing GACT (directly or via ArtifactCoords parsing that delegates to it) with strings that have a bad ':' placement: empty groupId, missing artifactId, or too many/few segments for the expected GACT shape.

Common situations: Hand-editing dependency coordinates in config; copying coords that include a version (6 segments G:A:C:T:V) into a GACT-only API; unresolved property placeholders leaving empty segments like "com.acme::jar".

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/24f00944aff3eef6. Report an issue: GitHub.