{"record":{"id":"443a2f05c3d0a5b9","repo":"quarkusio/quarkus","slug":"artifact-file-not-found-for-artifact","errorCode":null,"errorMessage":"Artifact file not found for ${artifact}","messagePattern":"Artifact file not found for (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"independent-projects/enforcer-rules/src/main/java/io/quarkus/enforcer/DeploymentDependencyRuleSupport.java","lineNumber":96,"sourceCode":"        execute(project, nonDeploymentArtifactsByGAV, directDepsByGAV);\n    }\n\n    protected abstract void execute(MavenProject project, Map<String, Artifact> nonDeploymentArtifactsByGAV,\n            Map<String, Dependency> directDepsByGAV)\n            throws EnforcerRuleException;\n\n    protected final String buildGAVKey(Artifact artifact) {\n        return artifact.getGroupId() + \":\" + artifact.getArtifactId() + \":\" + artifact.getVersion();\n    }\n\n    protected final Optional<String> parseDeploymentGAV(String gav, Artifact artifact) {\n        return DEPLOYMENT_GAV_CACHE.computeIfAbsent(gav, k -> parseDeploymentGAV(artifact));\n    }\n\n    private Optional<String> parseDeploymentGAV(Artifact artifact) {\n        File artifactFile = artifact.getFile();\n        if (artifactFile == null || !artifactFile.exists()) {\n            throw new IllegalStateException(\"Artifact file not found for \" + artifact);\n        }\n\n        Properties extProperties = new Properties();\n        if (artifactFile.isDirectory()) {\n            Path extPropertiesPath = artifactFile.toPath().resolve(EXT_PROPERTIES_PATH);\n            if (!Files.exists(extPropertiesPath)) {\n                return Optional.empty();\n            }\n            try (InputStreamReader isr = new InputStreamReader(Files.newInputStream(extPropertiesPath),\n                    StandardCharsets.UTF_8)) {\n                extProperties.load(isr);\n            } catch (IOException e) {\n                throw new UncheckedIOException(\"Failed to read \" + EXT_PROPERTIES_PATH + \" from \" + artifactFile, e);\n            }\n        } else {\n            try (ZipFile zipFile = new ZipFile(artifactFile)) {\n                ZipEntry entry = zipFile.getEntry(EXT_PROPERTIES_PATH);\n                if (entry == null) {","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/enforcer-rules/src/main/java/io/quarkus/enforcer/DeploymentDependencyRuleSupport.java#L78-L114","documentation":"DeploymentDependencyRuleSupport.parseDeploymentGAV reads a Quarkus runtime artifact's quarkus-extension.properties (EXT_PROPERTIES_PATH) to find its 'deployment-artifact' GAV. It first requires the artifact's local File to exist; if artifact.getFile() is null or the file does not exist on disk, it throws IllegalStateException 'Artifact file not found for <artifact>'.","triggerScenarios":"parseDeploymentGAV (via the cached wrapper called from BansRuntimeDependency / DeploymentDependencyRule) is given a Maven Artifact that has not been resolved — its file was never downloaded/copied into the local repository, e.g. an unresolved dependency or a provided-scope artifact with no backing file.","commonSituations":"Artifact resolved with scope that skips download; offline build where the jar was never fetched; a fake/partially-resolved Artifact object constructed programmatically in a test; corrupted local repository entry removed mid-build.","solutions":["Ensure dependencies are resolved before enforcing: bind the rule to a phase after dependency resolution or call artifactResolver.resolveArtifact for the artifact first","Verify the jar exists in the local repository (~/.m2/repository/...) and rebuild with network access","Check scope configuration — the artifact must actually be part of the resolved dependency set","For programmatic use, only pass artifacts whose getFile() is non-null and exists"],"exampleFix":"// before: inspecting an unresolved artifact\nrule.parseDeploymentGAV(unresolvedArtifact); // file == null\n// after: resolve first\nArtifactResult res = repoSystem.resolveArtifact(session, new ArtifactRequest(artifact, repos, null));\nrule.parseDeploymentGAV(artifact); // file now exists","handlingStrategy":"try-catch","validationCode":"// Java: guard before inspecting\nFile f = artifact.getFile();\nif (f == null || !f.exists()) {\n    throw new IllegalStateException(\"Resolve artifact before checking: \" + artifact);\n}","typeGuard":null,"tryCatchPattern":"try {\n    Optional<String> gav = support.getDeploymentGAV(artifact);\n} catch (IllegalStateException | UncheckedIOException e) {\n    getLog().warn(\"Could not read extension metadata for \" + artifact + \"; resolve artifacts first\", e);\n}","preventionTips":["Bind the enforcer rule to a lifecycle phase after dependency resolution","Never run builds with -o unless all artifacts are already cached","Check scope configuration so needed artifacts are actually resolved","In tests, resolve artifacts through the repository system rather than constructing bare Artifact instances"],"tags":["maven","enforcer","artifact-resolution","quarkus-build"],"backgroundTag":"artifact-resolution-failed","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"}