theonedev/onedev · error · NotFoundException

Commit not found

Error message

Commit not found

What it means

RepositoryResource.getCommit resolves a single commit by delegating to queryCommits with query "commit(<hash>)" and count 1. If the query returns no commits — the hash does not exist in the repository — it throws a NotFoundException with message "Commit not found" (HTTP 404).

Source

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

		var fieldSet = EnumSet.noneOf(LogCommand.Field.class);
		fieldSet.addAll(fields.stream().map(LogCommand.Field::valueOf).collect(toList()));
		
		return gitService.log(project, options, fieldSet);
    }
	
	@Api(order=86, description="Get specified commit")
	@Path("/{projectId}/commits/{commitHash}")
	@GET
    public LogCommit getCommit(
			@PathParam("projectId") Long projectId,
			@PathParam("commitHash") @Api(example="8cbec3d9eda2050a4ca0676767be3b6bf20251b8") String commitHash,
			@QueryParam("field") @Api(exampleProvider = "getFieldsExample", description = "Fields to return. Unspecified fields will return as null in returned commit object") List<String> fields) {
		var commits = queryCommits(projectId, "commit(" + commitHash + ")", 1, fields);
		if (!commits.isEmpty())
			return commits.iterator().next();
		else
			throw new NotFoundException("Commit not found");
    }

	@SuppressWarnings("unused")
	private static List<String> getFieldsExample() {
		return EnumSet.allOf(LogCommand.Field.class).stream().map(Enum::name).collect(toList());
	}
	
	@Api(order=90, description="Get children of specified directory")
	@Path("/{projectId}/directories/{revisionAndDirectory:.*}")
	@GET
	public List<DirectoryChild> getDirectory(
			@PathParam("projectId") Long projectId, 
			@PathParam("revisionAndDirectory") @NotEmpty @Api(example="some-branch-or-tag/path/to/directory") String revisionAndDirectory) {
		Project project = projectService.load(projectId);
		if (!SecurityUtils.canReadCode(project)) {
			throw new UnauthorizedException();
		}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Verify the commit hash exists in this specific project (git cat-commit or the UI) before calling the API.
  2. Confirm you are querying the correct projectId — commits are project-scoped.
  3. Use the full 40-character hash if a shortened hash is ambiguous or mis-copied.
  4. If the commit was force-pushed away, restore it via a ref or look it up in the original repository.

Example fix

// before: hash from a different repo
curl .../projects/42/commits/deadbeef  -> 404 Commit not found

// after: hash verified against project 42
curl .../projects/42/commits/8cbec3d9eda2050a4ca0676767be3b6bf20251b8
Defensive patterns

Strategy: try-catch

Validate before calling

// resolve the ref/hash first if your client has Git access
git rev-parse --verify <hash>^{commit} || echo "commit not present locally"

Type guard

function isFullHash(s) { return /^[0-9a-f]{40}$/.test(s); }

Try / catch

try {
  return getCommit(projectId, hash, fields);
} catch (e) {
  if (isNotFound(e)) return null; // commit not in this project — handle upstream
  throw e;
}

Prevention

When it happens

Trigger: GET .../commits/{commitHash} with a hash that is not reachable in the project's repository: a wrong/truncated hash, a hash from a fork or another project, or a commit on a force-pushed-away branch.

Common situations: Cross-project lookups (commit exists in fork, not in this project); history rewritten by force-push so old hashes vanish; typos or copying a short hash that was later rebased.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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