{"record":{"id":"16889d30c96e1b11","repo":"theonedev/onedev","slug":"build-number-has-to-be-specified-16889d","errorCode":null,"errorMessage":"build number has to be specified","messagePattern":"build number has to be specified","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server-plugin/server-plugin-report-markdown/src/main/java/io/onedev/server/plugin/report/markdown/MarkdownReportDownloadResource.java","lineNumber":46,"sourceCode":"\tprivate static final long serialVersionUID = 1L;\n\n\tprivate static final String PARAM_PROJECT = \"project\";\n\n\tprivate static final String PARAM_BUILD = \"build\";\n\n\tprivate static final String PARAM_REPORT = \"report\";\n\t\n\t@Override\n\tprotected ResourceResponse newResourceResponse(Attributes attributes) {\n\t\tPageParameters params = attributes.getParameters();\n\n\t\tString projectPath = params.get(PARAM_PROJECT).toString();\n\t\tProject project = OneDev.getInstance(ProjectService.class).findByPath(projectPath);\n\t\t\n\t\tLong buildNumber = params.get(PARAM_BUILD).toOptionalLong();\n\t\t\n\t\tif (buildNumber == null)\n\t\t\tthrow new IllegalArgumentException(\"build number has to be specified\");\n\t\t\n\t\tBuild build = OneDev.getInstance(BuildService.class).find(project, buildNumber);\n\n\t\tif (build == null) {\n\t\t\tString message = String.format(\"Unable to find build (project: %s, build number: %d)\", \n\t\t\t\t\tproject.getPath(), buildNumber);\n\t\t\tthrow new EntityNotFoundException(message);\n\t\t}\n\t\t\n\t\tString reportName = params.get(PARAM_REPORT).toOptionalString();\n\t\t\n\t\tif (reportName == null)\n\t\t\tthrow new IllegalArgumentException(\"Markdown report name has to be specified\");\n\t\tif (reportName.contains(\"..\"))\n\t\t\tthrow new ExplicitException(\"Invalid request path\");\n\t\t\n\t\tif (!SecurityUtils.canAccessReport(build, reportName))\n\t\t\tthrow new UnauthorizedException();","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-report-markdown/src/main/java/io/onedev/server/plugin/report/markdown/MarkdownReportDownloadResource.java#L28-L64","documentation":"MarkdownReportDownloadResource.newResourceResponse() requires a build number; when params.get(PARAM_BUILD).toOptionalLong() yields null it throws IllegalArgumentException 'build number has to be specified'. The resource cannot locate a report without knowing which build produced it.","triggerScenarios":"GET on the markdown report download resource omitting the build parameter (or supplying a non-numeric value so toOptionalLong returns null).","commonSituations":"Hand-built URLs missing the build parameter; API clients templating the URL with an empty/unset build variable.","solutions":["Include the build number parameter in the resource URL","Fix the URL template so the build variable is populated before requesting","Validate the build number client-side before constructing the URL"],"exampleFix":"// before\nGET /~resources/markdown-report/proj//report/coverage\n// after\nGET /~resources/markdown-report/proj/87/report/coverage","handlingStrategy":"validation","validationCode":"if (buildNumber == null || isNaN(Number(buildNumber))) throw new Error('build number has to be specified');","typeGuard":"function hasBuildNumber(params) { return params.get('build') != null && !isNaN(Number(params.get('build'))); }","tryCatchPattern":"try { fetch(url); } catch (IllegalArgumentException e) { // supply build param and retry }","preventionTips":["Interpolate build number from CI context before building the URL","Assert all required query params are non-empty in link builders","Fail fast client-side when template variables are unset"],"tags":["rest","missing-argument","report"],"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"}