theonedev/onedev · error · NotFoundException

Unable to find blob path '<path>' in revision '<revision>'

Error message

Unable to find blob path '<path>' in revision '<revision>'

What it means

This BlobIdent constructor parses a revision-and-path segment list (e.g. from a URL), then calls project.getMode(revision, path) to look up the git file mode of the path at that revision. A mode of 0 means the path does not exist in the revision's tree, so a NotFoundException is thrown to signal a missing blob.

Source

Thrown at server-core/src/main/java/io/onedev/server/git/BlobIdent.java:59

		this.path = path;
		this.mode = mode;
	}
	
	public BlobIdent(@Nullable String revision, @Nullable String path) {
		this(revision, path, FileMode.REGULAR_FILE.getBits());
	}
	
	public BlobIdent() {
	}
	
	public BlobIdent(Project project, List<String> segments) {
		RevisionAndPath revisionAndPath = RevisionAndPath.parse(project, segments); 
		revision = revisionAndPath.getRevision();
		path = revisionAndPath.getPath();
		if (path != null) {
			mode = project.getMode(revision, path);
			if (mode == 0) {
				throw new NotFoundException("Unable to find blob path '" + path
						+ "' in revision '" + revision + "'");
			}
		} else {
			mode = FileMode.TREE.getBits();
		}
	}
	
	public boolean isTree() {
		return mode != null && (FileMode.TYPE_MASK & mode) == FileMode.TYPE_TREE;
	}
	
	public boolean isGitLink() {
		return mode != null && (FileMode.TYPE_MASK & mode) == FileMode.TYPE_GITLINK;
	}
	
	public boolean isSymbolLink() {
		return mode != null && (FileMode.TYPE_MASK & mode) == FileMode.TYPE_SYMLINK;
	}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Verify the path exists at that revision: project.getMode(revision, path) != 0, or use git ls-tree / list the directory before constructing BlobIdent.
  2. Check the revision (branch/tag/commit) actually contains the file; try the default branch or the commit that added the file.
  3. Catch NotFoundException and return a 404-style response or an empty-state UI for the caller.
  4. If the file was moved, look up the new path (e.g. via rename detection or project history) and retry with the updated path.

Example fix

// before
BlobIdent ident = new BlobIdent(project, List.of("main", "docs", "removed.md")); // throws if absent
// after
if (project.getMode("main", "docs/removed.md") != 0) {
    BlobIdent ident = new BlobIdent(project, List.of("main", "docs", "removed.md"));
} else {
    throw new NotFoundException("docs/removed.md not on main");
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (project.getMode(revision, path) == 0) {
    // path absent at revision: skip or return not-found
}

Type guard

boolean blobExists(Project project, String revision, String path) {
    return path != null && project.getMode(revision, path) != 0;
}

Try / catch

try {
    BlobIdent ident = new BlobIdent(project, segments);
} catch (NotFoundException e) {
    // render 404 / empty state
}

Prevention

When it happens

Trigger: Constructing new BlobIdent(project, segments) where the parsed path does not exist in the parsed revision: wrong file name, file exists only on another branch/commit, path was deleted or renamed, or typo in the URL path segment.

Common situations: Browsing a stale link to a file deleted after the link was made; requesting a file from a branch that doesn't contain it; typos in repository file paths in REST URLs; checking out a tag where the file never existed.

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/791d53934d327981. Report an issue: GitHub.