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
- Provide coordinates in groupId:artifactId[:classifier][:type] form with non-empty groupId and artifactId
- Remove version segments if the target API is GACT-only (version is handled by ArtifactCoords.split)
- Resolve ${...} placeholders so no segment is empty
- 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
- Use ArtifactCoords factories instead of raw GACT construction
- Keep version out of GACT strings; versions go through ArtifactCoords.parse
- Check for empty segments caused by unresolved placeholders
- Centralize coordinate parsing in one validated helper
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
- One of type, version or separating them ':' is missing from
- Invalid coordinates '${str}': groupId and artifactId separat
- One of groupId or artifactId is missing from '${str.substrin
- Invalid workspace module ID string: ${str}
- ArtifactCoordsSegmentPattern.of() expects groupId:artifactId
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/24f00944aff3eef6.
Report an issue: GitHub.