theonedev/onedev · error · NotAcceptableException
Specified path is not a directory: ${blobIdent.path}
Error message
Specified path is not a directory: ${blobIdent.path} What it means
RepositoryResource.getDirectory parses the 'revisionAndDirectory' path parameter into a BlobIdent and requires it to designate a tree. If the path actually points to a blob (file) rather than a directory, it throws a NotAcceptableException with message "Specified path is not a directory: <path>".
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/RepositoryResource.java:325
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();
}
List<String> revisionAndPathSegments = Splitter.on('/').splitToList(revisionAndDirectory);
BlobIdent blobIdent = new BlobIdent(project, revisionAndPathSegments);
if (!blobIdent.isTree()) {
throw new NotAcceptableException("Specified path is not a directory: " + blobIdent.path);
}
ObjectId revId = project.getObjectId(blobIdent.revision, true);
List<DirectoryChild> children = new ArrayList<>();
for (BlobIdent childIdent: gitService.getChildren(
project, revId, blobIdent.path, BlobIdentFilter.ALL, false)) {
DirectoryChild child = new DirectoryChild();
child.path = childIdent.path;
child.isFile = (FileMode.TYPE_MASK & childIdent.mode) == FileMode.TYPE_FILE;
children.add(child);
}
return children;
}
@Api(order=100, description="Get metadata and content of specified file")
@Path("/{projectId}/files/{revisionAndFile:.*}")View on GitHub (pinned to d44925c47c)
Solutions
- Point the path at a directory — drop any trailing file segment (request 'main/src' not 'main/src/App.java').
- If you need file contents, call the getFile endpoint instead of getDirectory.
- When walking listings programmatically, branch on the entry type returned by DirectoryChild (file vs directory) before recursing.
Example fix
// before curl .../projects/42/files/main/README.md // file path // after curl .../projects/42/files/main // directory path
Defensive patterns
Strategy: validation
Validate before calling
// when walking listings, only recurse into directory children
if (child.type === "directory") {
await getDirectory(projectId, `${revision}/${child.path}`);
} Type guard
function isDirectoryPath(p) { return !path.extname(p) || p.endsWith("/"); } // heuristic; confirm via listing Try / catch
try {
return await getDirectory(projectId, revAndDir);
} catch (e) {
if (isNotAcceptable(e) && /not a directory/.test(e.message)) {
return await getFile(projectId, revAndDir); // fallback to file read
}
throw e;
} Prevention
- Branch on the child type returned by DirectoryChild before recursing.
- Strip file segments from paths before calling the directory endpoint.
- Remember the endpoint expects 'revision/directory', not 'revision/file'.
When it happens
Trigger: GET .../files/{revisionAndDirectory} where the path portion of revisionAndDirectory names a file (e.g. 'main/src/App.java') instead of a directory ('main/src').
Common situations: Clients walking a tree that mistakenly pass file entries returned by a previous listing; trailing-path bugs that drop or misplace the directory segment; confusing a symlink/file with a folder.
Related errors
- Specified path is not a file: ${blobIdent.path}
- Ref name is required when commit hash is specified
- Either commit hash, branch or tag should be specified
- Invalid old path: <oldPath>
- Invalid new path: <path>
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/4f266f44b6fb5b58.
Report an issue: GitHub.