theonedev/onedev · error · ExplicitException
Artifact path has to be specified
Error message
Artifact path has to be specified
What it means
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.
Source
Thrown at server-core/src/main/java/io/onedev/server/web/resource/ArtifactResource.java:57
@Override
protected ResourceResponse newResourceResponse(Attributes attributes) {
PageParameters params = attributes.getParameters();
Long projectId = params.get(PARAM_PROJECT).toLong();
Long buildNumber = params.get(PARAM_BUILD).toLong();
List<String> pathSegments = new ArrayList<>();
for (int i = 0; i < params.getIndexedCount(); i++) {
String pathSegment = params.get(i).toString();
if (pathSegment.contains(".."))
throw new ExplicitException("Invalid request path");
if (pathSegment.length() != 0)
pathSegments.add(pathSegment);
}
if (pathSegments.isEmpty())
throw new ExplicitException("Artifact path has to be specified");
String artifactPath = Joiner.on("/").join(pathSegments);
FileInfo fileInfo = null;
if (!SecurityUtils.isSystem()) {
Project project = OneDev.getInstance(ProjectService.class).load(projectId);
Build build = OneDev.getInstance(BuildService.class).find(project, buildNumber);
if (build == null) {
String message = String.format("Unable to find build (project: %s, build number: %d)",
project.getPath(), buildNumber);
throw new EntityNotFoundException(message);
}
if (!SecurityUtils.canAccessProject(build.getProject()))
throw new UnauthorizedException();
View on GitHub (pinned to d44925c47c)
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
Example fix
// before GET /~resources/artifact/1/5 // after GET /~resources/artifact/1/5/target/app.jar
Defensive patterns
Strategy: validation
Validate before calling
if (!artifactPath || artifactPath.split('/').filter(Boolean).length === 0) throw new Error('artifact path is required, e.g. target/app.jar');
const url = `~/.artifact/${projectId}/${buildNumber}/${artifactPath}`; Type guard
function hasArtifactPath(p) { return typeof p === 'string' && p.split('/').some(s => s.length > 0); } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- revision parameter has to be specified
- Unable to find build (project: %s, build number: %d)
- Parameter 'attachment-group' has to be specified
- Revision and path should be specified
- Unauthenticated
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/078c94b0becbef8a.
Report an issue: GitHub.