{"record":{"id":"4996bceb38adcddd","repo":"theonedev/onedev","slug":"revision-parameter-has-to-be-specified","errorCode":null,"errorMessage":"revision parameter has to be specified","messagePattern":"revision parameter has to be specified","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/web/resource/ArchiveResource.java","lineNumber":65,"sourceCode":"\tprivate static final String PARAM_PROJECT = \"project\";\n\t\n\tprivate static final String PARAM_REVISION = \"revision\";\n\t\n\tprivate static final String PARAM_FORMAT = \"format\";\n\t\n\tpublic static final String FORMAT_ZIP = \"zip\";\n\t\n\tpublic static final String FORMAT_TGZ = \"tgz\";\n\t\n\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\t\n\t\tString revision = params.get(PARAM_REVISION).toString();\n\t\tif (StringUtils.isBlank(revision))\n\t\t\tthrow new IllegalArgumentException(\"revision parameter has to be specified\");\n\t\t\n\t\tString format = params.get(PARAM_FORMAT).toString();\n\t\tif (!FORMAT_ZIP.equals(format) && !FORMAT_TGZ.equals(format)) {\n\t\t\tthrow new IllegalArgumentException(\"format parameter should be specified either zip or tar.gz\");\n\t\t}\n\t\t\n\t\tif (!SecurityUtils.isSystem()) {\n\t\t\t// Perform database operations only if it is not a cluster access to avoid possible deadlocks\n\t\t\tProject project = OneDev.getInstance(ProjectService.class).load(projectId);\n\t\t\tif (!SecurityUtils.canReadCode(project)) \n\t\t\t\tthrow new UnauthorizedException();\n\t\t}\n\t\t\n\t\tResourceResponse response = new ResourceResponse();\n\t\tresponse.setContentType(MimeTypes.OCTET_STREAM);\n\t\t\n\t\tresponse.disableCaching();\n\t\t","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/web/resource/ArchiveResource.java#L47-L83","documentation":"OneDev's ArchiveResource serves project source archives (zip/tar.gz) over a REST-style resource URL. Before generating the archive it parses query parameters and rejects the request with this IllegalArgumentException when the required 'revision' parameter is blank or absent, because an archive cannot be generated without knowing which commit/branch/tag to archive.","triggerScenarios":"Hitting the archive resource URL (~/.archive or project archive endpoint) with only the 'project' (and optionally 'format') parameters while omitting or leaving empty the 'revision' query parameter.","commonSituations":"Hand-built URLs in scripts or CI steps that forgot revision; a templated URL where the revision variable interpolated to empty (e.g. unset CI variable for branch/commit SHA); URL encoding stripping the parameter.","solutions":["Add the revision query parameter to the archive URL, e.g. ?project=<id>&revision=<commit-sha-or-branch>&format=zip","If the revision comes from a variable, verify it is non-empty before constructing the URL (echo/check in the script or CI job)","Use OneDev's UI 'Download archive' action to obtain a correctly formed URL and compare with yours"],"exampleFix":"// before\nGET /~resources/archive?project=1&format=zip\n// after\nGET /~resources/archive?project=1&revision=abc1234&format=zip","handlingStrategy":"validation","validationCode":"if (!revision) throw new Error('archive URL requires a non-empty revision (commit SHA, branch, or tag)');\nconst url = `~/.archive?project=${projectId}&revision=${encodeURIComponent(revision)}&format=zip`;","typeGuard":null,"tryCatchPattern":"try { await fetch(url); } catch (e) { console.error('Archive request failed - check revision/format params and permissions:', e); }","preventionTips":["Always include revision in archive URLs","Validate revision variables are non-empty before interpolating","Copy canonical URLs from the OneDev UI download action"],"tags":["http","missing-parameter","archive"],"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-14T05:17:10.506Z"}