{"record":{"id":"078c94b0becbef8a","repo":"theonedev/onedev","slug":"artifact-path-has-to-be-specified","errorCode":null,"errorMessage":"Artifact path has to be specified","messagePattern":"Artifact path has to be specified","errorType":"exception","errorClass":"ExplicitException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/web/resource/ArtifactResource.java","lineNumber":57,"sourceCode":"\t@Override\n\tprotected ResourceResponse newResourceResponse(Attributes attributes) {\n\t\tPageParameters params = attributes.getParameters();\n\n\t\tLong projectId = params.get(PARAM_PROJECT).toLong();\n\t\tLong buildNumber = params.get(PARAM_BUILD).toLong();\n\t\t\n\t\tList<String> pathSegments = new ArrayList<>();\n\n\t\tfor (int i = 0; i < params.getIndexedCount(); i++) {\n\t\t\tString pathSegment = params.get(i).toString();\n\t\t\tif (pathSegment.contains(\"..\"))\n\t\t\t\tthrow new ExplicitException(\"Invalid request path\");\n\t\t\tif (pathSegment.length() != 0)\n\t\t\t\tpathSegments.add(pathSegment);\n\t\t}\n\t\t\n\t\tif (pathSegments.isEmpty())\n\t\t\tthrow new ExplicitException(\"Artifact path has to be specified\");\n\t\t\n\t\tString artifactPath = Joiner.on(\"/\").join(pathSegments);\n\t\t\n\t\tFileInfo fileInfo = null;\n\t\tif (!SecurityUtils.isSystem()) {\n\t\t\tProject project = OneDev.getInstance(ProjectService.class).load(projectId);\n\t\t\t\n\t\t\tBuild build = OneDev.getInstance(BuildService.class).find(project, buildNumber);\n\n\t\t\tif (build == null) {\n\t\t\t\tString message = String.format(\"Unable to find build (project: %s, build number: %d)\", \n\t\t\t\t\t\tproject.getPath(), buildNumber);\n\t\t\t\tthrow new EntityNotFoundException(message);\n\t\t\t}\n\t\t\t\n\t\t\tif (!SecurityUtils.canAccessProject(build.getProject()))\n\t\t\t\tthrow new UnauthorizedException();\n\t\t\t","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/web/resource/ArtifactResource.java#L39-L75","documentation":"ArtifactResource requires an artifact file path. After filtering empty path segments, if no segments remain it throws ExplicitException 'Artifact path has to be specified', since the resource is meant to download a specific artifact file, not a listing.","triggerScenarios":"Calling the artifact resource with project/build parameters but no indexed path segments (empty trailing path), or a path consisting only of empty segments like double slashes.","commonSituations":"URL template with an unfilled path variable; URL ending in a separator so the path portion is dropped; scripts that pass an empty artifact path variable.","solutions":["Append the artifact file path to the URL, e.g. .../artifact/<project>/<build>/target/app.jar","Verify the variable holding the artifact path is non-empty in your script/CI step","Browse the build's artifacts in the OneDev UI and copy the exact link to confirm the path"],"exampleFix":"// before\nGET /~resources/artifact/1/5\n// after\nGET /~resources/artifact/1/5/target/app.jar","handlingStrategy":"validation","validationCode":"if (!artifactPath || artifactPath.split('/').filter(Boolean).length === 0) throw new Error('artifact path is required, e.g. target/app.jar');\nconst url = `~/.artifact/${projectId}/${buildNumber}/${artifactPath}`;","typeGuard":"function hasArtifactPath(p) { return typeof p === 'string' && p.split('/').some(s => s.length > 0); }","tryCatchPattern":null,"preventionTips":["Check path variables are populated before URL construction","Copy exact artifact links from the build page","Avoid trailing separators that can drop the path segment"],"tags":["http","missing-parameter","artifact"],"backgroundTag":"missing-required-argument","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}