{"record":{"id":"25630dc5310e353a","repo":"apache/maven","slug":"for-artifact-an-attached-artifact-must-have-a","errorCode":null,"errorMessage":"For artifact {}: An attached artifact must have a different ID than its corresponding main artifact.","messagePattern":"For artifact (.+?): An attached artifact must have a different ID than its corresponding main artifact\\.","errorType":"exception","errorClass":"InvalidArtifactRTException","httpStatus":null,"severity":"error","filePath":"impl/maven-core/src/main/java/org/apache/maven/project/artifact/AttachedArtifact.java","lineNumber":60,"sourceCode":"    private final Artifact parent;\n\n    public AttachedArtifact(Artifact parent, String type, String classifier, ArtifactHandler artifactHandler) {\n        super(\n                parent.getGroupId(),\n                parent.getArtifactId(),\n                parent.getVersionRange(),\n                parent.getScope(),\n                type,\n                classifier,\n                artifactHandler,\n                parent.isOptional());\n\n        setDependencyTrail(Collections.singletonList(parent.getId()));\n\n        this.parent = parent;\n\n        if (getId().equals(parent.getId())) {\n            throw new InvalidArtifactRTException(\n                    parent.getGroupId(),\n                    parent.getArtifactId(),\n                    parent.getVersion(),\n                    parent.getType(),\n                    \"An attached artifact must have a different ID\" + \" than its corresponding main artifact.\");\n        }\n    }\n\n    public AttachedArtifact(Artifact parent, String type, ArtifactHandler artifactHandler) {\n        this(parent, type, null, artifactHandler);\n    }\n\n    @Override\n    public void setArtifactId(String artifactId) {\n        throw new UnsupportedOperationException(\n                \"Cannot change the artifactId for an attached artifact.\" + \" It is derived from the main artifact.\");\n    }\n","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-core/src/main/java/org/apache/maven/project/artifact/AttachedArtifact.java#L42-L78","documentation":"AttachedArtifact models a secondary artifact (sources, javadoc, tests, custom classifier) attached to a project's main artifact: it inherits groupId/artifactId/version from the parent and may differ only in type and classifier. The constructor compares both ids and throws InvalidArtifactRTException (a runtime exception) when they match, i.e. when type and classifier are identical to the main artifact's, because the attachment would collide with the artifact it is attached to.","triggerScenarios":"new AttachedArtifact(main, type, classifier, handler) where type equals main.getType() and classifier equals main's classifier (typically \"jar\"/null). The same rule surfaces through MavenProjectHelper.attachArtifact(project, type, classifier, file) with the same combination.","commonSituations":"A mojo attaching an extra jar without a classifier to a jar-packaged project; copy-pasted attachArtifact calls where only the file parameter changed; re-attaching the main artifact's own file.","solutions":["Set a distinct classifier (sources, javadoc, tests, ...)","Or attach with a different type (e.g. zip instead of the packaging type)","Verify you are not re-attaching the main artifact itself"],"exampleFix":"// before\nprojectHelper.attachArtifact(project, \"jar\", null, extraFile); // jar project, type jar, no classifier\n\n// after\nprojectHelper.attachArtifact(project, \"jar\", \"extra\", extraFile);","handlingStrategy":"validation","validationCode":"boolean collidesWithMain = type.equals(main.getType()) && Objects.equals(classifier, main.getClassifier());\nif (collidesWithMain) {\n    throw new IllegalArgumentException(\"attached artifact needs a distinct type or classifier\");\n}\nnew AttachedArtifact(main, type, classifier, handler);","typeGuard":null,"tryCatchPattern":"try {\n    new AttachedArtifact(main, type, classifier, handler);\n} catch (InvalidArtifactRTException e) {\n    // message tells you the attached id equals the main id: pick another classifier or type\n    log.warn(\"attach rejected for {}: choose a different classifier/type\", main.getId());\n}","preventionTips":["Always give attached artifacts a classifier unless their type differs from the packaging","Prefer MavenProjectHelper.attachArtifact over constructing the deprecated AttachedArtifact directly"],"tags":["maven","artifact","attached-artifact","classifier","coordinates"],"backgroundTag":"duplicate-artifact-coordinates","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}