theonedev/onedev · error · IllegalArgumentException

Markdown report name has to be specified

Error message

Markdown report name has to be specified

What it means

MarkdownReportDownloadResource requires the report name parameter; when params.get(PARAM_REPORT).toOptionalString() returns null it throws IllegalArgumentException 'Markdown report name has to be specified'. A subsequent '..' check throws 'Invalid request path' and access is gated by SecurityUtils.canAccessReport.

Source

Thrown at server-plugin/server-plugin-report-markdown/src/main/java/io/onedev/server/plugin/report/markdown/MarkdownReportDownloadResource.java:59

		Project project = OneDev.getInstance(ProjectService.class).findByPath(projectPath);
		
		Long buildNumber = params.get(PARAM_BUILD).toOptionalLong();
		
		if (buildNumber == null)
			throw new IllegalArgumentException("build number has to be specified");
		
		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);
		}
		
		String reportName = params.get(PARAM_REPORT).toOptionalString();
		
		if (reportName == null)
			throw new IllegalArgumentException("Markdown report name has to be specified");
		if (reportName.contains(".."))
			throw new ExplicitException("Invalid request path");
		
		if (!SecurityUtils.canAccessReport(build, reportName))
			throw new UnauthorizedException();
			
		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);
		}
		
		String markdownPath = Joiner.on("/").join(pathSegments);
		
		File buildDir = build.getDir();

View on GitHub (pinned to d44925c47c)

Solutions

  1. Add the report name to the request URL (the name under which the report was published)
  2. Ensure the pipeline actually publishes the markdown report and use its exact name
  3. Fix the URL template so the report variable is filled

Example fix

// before
GET /~resources/markdown-report/proj/50/report/
// after
GET /~resources/markdown-report/proj/50/report/test-summary
Defensive patterns

Strategy: validation

Validate before calling

const reportName = params.get('report');
if (reportName == null || reportName.length === 0) throw new Error('Markdown report name has to be specified');

Type guard

function hasReportName(params) { const r = params.get('report'); return typeof r === 'string' && r.length > 0 && !r.includes('..'); }

Try / catch

try { fetch(url); } catch (IllegalArgumentException | ExplicitException e) { // fill report param and retry }

Prevention

When it happens

Trigger: GET on the markdown report download resource with no report parameter in the URL.

Common situations: URL builders omitting the report name; links to the report collection root rather than a named report; template variable left unset.

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


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/c51d2c1ffd10f50f. Report an issue: GitHub.