theonedev/onedev · error · IllegalArgumentException

attachment parameter has to be specified

Error message

attachment parameter has to be specified

What it means

AttachmentResource requires the 'attachment' query/path parameter naming the file to download. If the parameter is absent or blank, newResourceResponse throws IllegalArgumentException("attachment parameter has to be specified"), which the resource layer reports to the client as a 400-style error.

Source

Thrown at server-core/src/main/java/io/onedev/server/web/resource/AttachmentResource.java:96

				if (OneDev.getInstance(PullRequestService.class).find(attachmentGroup) != null
						|| OneDev.getInstance(CodeCommentService.class).findByUUID(attachmentGroup) != null) {
					if (!SecurityUtils.canReadCode(project))
						throw new UnauthorizedException();
				} else if ((issue = OneDev.getInstance(IssueService.class).find(attachmentGroup)) != null) {
					if (!SecurityUtils.canAccessIssue(issue))
						throw new UnauthorizedException();
				} else if ((build = OneDev.getInstance(BuildService.class).find(attachmentGroup)) != null) {
					if (!SecurityUtils.canAccessProject(build.getProject()))
						throw new UnauthorizedException();
				} else if (!SecurityUtils.canAccessProject(project)) {
					throw new UnauthorizedException();
				}
			}
		}

		String attachment = params.get(PARAM_ATTACHMENT).toString();
		if (StringUtils.isBlank(attachment))
			throw new IllegalArgumentException("attachment parameter has to be specified");
		else if (attachment.contains(".."))
			throw new IllegalArgumentException("Invalid attachment parameter");

		ResourceResponse response = new ResourceResponse();
		response.setContentLength(getAttachmentService().getAttachmentInfo(projectId, attachmentGroup, attachment).getLength());
		
		response.getHeaders().addHeader("X-Content-Type-Options", "nosniff");
		response.setContentType(MimeTypes.OCTET_STREAM);

		response.setFileName(URLEncoder.encode(attachment, UTF_8));

		response.setWriteCallback(new WriteCallback() {

			@Override
			public void writeData(Attributes attributes) throws IOException {
				String activeServer = getProjectService().getActiveServer(projectId, true);
				ClusterService clusterService = OneDev.getInstance(ClusterService.class);
				if (activeServer.equals(clusterService.getLocalServerAddress())) {

View on GitHub (pinned to d44925c47c)

Solutions

  1. Append the attachment file name as the query parameter, e.g. ?attachment=report.pdf (URL-encode special characters).
  2. Fix the code or template that builds the URL so it always includes the attachment parameter.
  3. Verify the exact parameter name against AttachmentResource.PARAM_ATTACHMENT in the OneDev version in use.

Example fix

// before
GET /~resource/attachments/1/issue-42          -> 400
// after
GET /~resource/attachments/1/issue-42?attachment=trace.log
Defensive patterns

Strategy: validation

Validate before calling

if (!attachmentName || attachmentName.trim() === '') {
  throw new Error('attachment query parameter is required, e.g. ?attachment=report.pdf');
}

Type guard

function hasAttachment(params) {
  return typeof params.attachment === 'string' && params.attachment.length > 0;
}

Try / catch

try { const res = await fetch(url); } catch (e) { if (String(e.message).includes('attachment parameter')) console.error('URL must include ?attachment=<name>'); else throw e; }

Prevention

When it happens

Trigger: GET /~resource/attachments/<projectId>/<group> without the PARAM_ATTACHMENT query parameter, or with an empty value (params.get(PARAM_ATTACHMENT).toString() is blank).

Common situations: Hand-built URLs missing the ?attachment= part; template/URL-generation bug dropping the query string; scripts stripping parameters containing special characters without encoding.

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/0ee278274b96b17f. Report an issue: GitHub.