{"record":{"id":"768a36d652395353","repo":"quarkusio/quarkus","slug":"type-must-not-be-empty","errorCode":null,"errorMessage":"type must not be empty","messagePattern":"type must not be empty","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/bootstrap/app-model/src/main/java/io/quarkus/sbom/Purl.java","lineNumber":201,"sourceCode":"            subpath = null;\n        }\n\n        return new Purl(type, namespace, name, version, qualifiers, subpath);\n    }\n\n    private final String type;\n    private final String namespace;\n    private final String name;\n    private final String version;\n    private final Map<String, String> qualifiers;\n    private final String subpath;\n    private volatile String canonical;\n\n    private Purl(String type, String namespace, String name, String version,\n            Map<String, String> qualifiers, String subpath) {\n        Objects.requireNonNull(type, \"type is required\");\n        if (type.isEmpty()) {\n            throw new IllegalArgumentException(\"type must not be empty\");\n        }\n        validateType(type);\n        this.type = type.toLowerCase(Locale.ROOT);\n        this.namespace = namespace == null || namespace.isEmpty() ? null : namespace;\n        Objects.requireNonNull(name, \"name is required\");\n        if (name.isEmpty()) {\n            throw new IllegalArgumentException(\"name must not be empty\");\n        }\n        if (TYPE_MAVEN.equals(this.type) && this.namespace == null) {\n            throw new IllegalArgumentException(\"Maven PURL is missing a namespace (groupId) for name (artifactId) \" + name);\n        }\n        this.name = TYPE_NPM.equals(this.type) ? name.toLowerCase(Locale.ROOT) : name;\n        this.version = version;\n        this.qualifiers = qualifiers == null || qualifiers.isEmpty()\n                ? Map.of()\n                : qualifiers;\n        this.subpath = normalizeSubpath(subpath);\n    }","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/sbom/Purl.java#L183-L219","documentation":"Guard in the private Purl constructor: the type component of the package URL was non-null but empty (e.g. 'pkg:/name' with the type omitted). The type segment is mandatory in a purl, so construction fails.","triggerScenarios":"Programmatic Purl construction via factory methods (e.g. Purl.ofMaven(...) / builder) passing an empty type; parse() normally guarantees this, so direct construction with empty type is the trigger.","commonSituations":"Building purls dynamically where the type variable is uninitialized or stripped (e.g. empty config value for artifact type).","solutions":["Supply a valid type like 'maven', 'npm', 'gem' before constructing","Check the source of the type value (config/variable) for empty strings","Use Purl.parse() on a complete purl string instead of assembling components"],"exampleFix":"// before\nPurl p = Purl.of(type, namespace, name); // type == \"\"\n// after\nif (type == null || type.isEmpty()) { throw new IllegalStateException(\"artifact type missing\"); }\nPurl p = Purl.of(type, namespace, name);","handlingStrategy":"validation","validationCode":"if (type == null || type.isEmpty()) { throw new IllegalArgumentException(\"purl type required\"); }","typeGuard":"boolean hasValidType(String t) { return t != null && !t.isEmpty() && t.matches(\"[a-zA-Z0-9._-]+\"); }","tryCatchPattern":"try { Purl p = Purl.of(type, ns, name); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"type must not be empty\")) { type = inferType(artifact); p = Purl.of(type, ns, name); } else { throw e; } }","preventionTips":["Default the type to 'maven' for Maven builds","Validate config-driven type values before use","Prefer Purl.ofMaven/parse over manual component assembly"],"tags":["sbom","purl","validation"],"backgroundTag":"invalid-package-url","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"}