theonedev/onedev · error · NotAcceptableException

Branch and file should be specified

Error message

Branch and file should be specified

What it means

RepositoryResource.editFile requires the 'revisionAndPath' parameter to contain both a revision and a file path. When the project has a default branch and the parsed RevisionAndPath has no path component — or when there are fewer than two path segments in the no-default-branch case — it throws a NotAcceptableException with message "Branch and file should be specified".

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/RepositoryResource.java:393

	public FileEditResponse editFile(
			@PathParam("projectId") Long projectId, 
			@PathParam("branchAndFile") @NotEmpty @Api(example="test-branch/path/to/file") String branchAndFile, 
			@NotNull FileEditRequest request) {
		Project project = projectService.load(projectId);
		
		List<String> revisionAndPathSegments = Splitter.on('/').splitToList(branchAndFile);
		RevisionAndPath revisionAndPath;
		String refName;
		ObjectId oldCommitId;
		if (project.getDefaultBranch() != null) {
			revisionAndPath = RevisionAndPath.parse(project, revisionAndPathSegments);
			RefFacade ref = project.getBranchRef(revisionAndPath.getRevision());
			if (ref == null) 
				throw new NotAcceptableException("Not a branch: " + revisionAndPath.getRevision());
			refName = ref.getName();
			oldCommitId = ref.getObjectId();
			if (revisionAndPath.getPath() == null)
				throw new NotAcceptableException("Branch and file should be specified");
		} else {
			if (revisionAndPathSegments.size() < 2)
				throw new NotAcceptableException("Branch and file should be specified");
			revisionAndPath = new RevisionAndPath(
					revisionAndPathSegments.get(0), 
					StringUtils.join(revisionAndPathSegments.subList(1, revisionAndPathSegments.size())));
			refName = GitUtils.branch2ref(revisionAndPath.getRevision());
			oldCommitId = ObjectId.zeroId();
		}

		if (!SecurityUtils.canModifyFile(project, revisionAndPath.getRevision(), revisionAndPath.getPath())) 
			throw new UnauthorizedException();

		Map<String, BlobContent> newBlobs = new HashMap<>();
		
		Set<String> oldPaths = new HashSet<>();
		if (!oldCommitId.equals(ObjectId.zeroId()) 
				&& gitService.getMode(project, oldCommitId, revisionAndPath.getPath()) != 0) {

View on GitHub (pinned to d44925c47c)

Solutions

  1. Include both segments in the parameter: 'branch-name/path/to/file'.
  2. Check that slashes in the path are not swallowed by your HTTP client or URL encoder.
  3. When no default branch exists, ensure at least two segments (revision plus at least one path element) are supplied.

Example fix

// before
curl -X PUT .../projects/42/files/main   // no file path

// after
curl -X PUT .../projects/42/files/main/README.md
Defensive patterns

Strategy: validation

Validate before calling

const segments = revisionAndPath.split("/");
if (segments.length < 2 || !segments.slice(1).join("/")) {
  throw new Error("revisionAndPath must be 'branch/path/to/file'");
}

Try / catch

try {
  await editFile(projectId, revisionAndPath, changes);
} catch (e) {
  if (isNotAcceptable(e) && e.message === "Branch and file should be specified") {
    // fix the URL: append the file path segment and retry
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the file-edit endpoint with only a branch name and no file path (e.g. revisionAndPath = 'main' with no '/file' part), or with a single segment when no default branch is set.

Common situations: URL-encoding bugs that strip the path after the slash; scripts concatenating branch and path incorrectly; testing the endpoint with just a branch to probe behavior.

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/41de2fc483124abb. Report an issue: GitHub.