theonedev/onedev · error · NotAcceptableException

Not a branch: ${revisionAndPath.getRevision()}

Error message

Not a branch: ${revisionAndPath.getRevision()}

What it means

RepositoryResource.editFile only allows edits against a branch when the project has a default branch configured. It parses 'revisionAndPath' and looks up project.getBranchRef(revision); if the revision is not a branch (e.g. a tag, a raw commit hash, or a made-up name), it throws a NotAcceptableException with message "Not a branch: <revision>" because edits must land on a branch ref.

Source

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

	@Api(order=110, description="Create, update, or delete specified file. Return hash of resulting commit", 
			example="46c001b04cba0ca41588841f1ca32f50b582ee9b")
	@Path("/{projectId}/files/{branchAndFile:.*}")
	@POST
	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<>();

View on GitHub (pinned to d44925c47c)

Solutions

  1. Pass a branch name as the revision segment (e.g. 'main/path/to/file').
  2. If you need to edit a file at a tag/commit, create or use a branch pointing there first.
  3. List the project's branches to confirm the exact branch name and spelling.

Example fix

// before: editing against a tag
curl -X PUT .../projects/42/files/v1.0.0/README.md

// after: editing against a branch
curl -X PUT .../projects/42/files/main/README.md
Defensive patterns

Strategy: validation

Validate before calling

// resolve the revision to a branch before editing
const branch = await getBranch(projectId, revision);
if (!branch) {
  throw new Error(`'${revision}' is not a branch; edits require a branch name`);
}

Try / catch

try {
  await editFile(projectId, revisionAndPath, changes);
} catch (e) {
  if (isNotAcceptable(e) && e.message.startsWith("Not a branch:")) {
    // create a working branch from the tag/commit, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: PUT/POST to the file-edit endpoint with revisionAndPath whose revision segment is a tag, commit SHA, or non-existent ref, on a project that has a default branch.

Common situations: Automation tools editing files on a tagged release instead of a branch; scripts passing a commit hash thinking any revision works; typos in branch names ('master' vs 'main').

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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