theonedev/onedev · error · BlobEditException
Invalid new path: <path>
Error message
Invalid new path: <path>
What it means
The BlobEdits constructor normalizes each key of the newBlobs map via GitUtils.normalizePath. Keys that are empty, absolute, or contain '..' segments normalize to null and cause a BlobEditException("Invalid new path: ..."). This validates the destination paths of created/modified files before any git operation is attempted.
Source
Thrown at server-core/src/main/java/io/onedev/server/git/BlobEdits.java:51
this(new HashSet<>(), new HashMap<>());
}
public BlobEdits(Set<String> oldPaths, Map<String, BlobContent> newBlobs) {
this.oldPaths = new HashSet<>();
for (String oldPath: oldPaths) {
String normalizedPath = GitUtils.normalizePath(oldPath);
if (normalizedPath != null)
this.oldPaths.add(normalizedPath);
else
throw new BlobEditException("Invalid old path: " + oldPath);
}
this.newBlobs = new HashMap<>();
for (Map.Entry<String, BlobContent> entry: newBlobs.entrySet()) {
String normalizedPath = GitUtils.normalizePath(entry.getKey());
if (normalizedPath != null)
this.newBlobs.put(normalizedPath, entry.getValue());
else
throw new BlobEditException("Invalid new path: " + entry.getKey());
}
}
public Set<String> getOldPaths() {
return oldPaths;
}
public Map<String, BlobContent> getNewBlobs() {
return newBlobs;
}
public void applySuggestion(Project project, Mark mark, List<String> suggestion, ObjectId commitId) {
Map<String, BlobContent> newBlobs = getNewBlobs();
BlobContent blobContent = newBlobs.get(mark.getPath());
if (blobContent == null) {
BlobIdent newBlobIdent = new BlobIdent(commitId.name(), mark.getPath());
Blob newBlob = project.getBlob(newBlobIdent, false);
if (newBlob == null || newBlob.getText() == null || newBlob.getLfsPointer() != null)View on GitHub (pinned to d44925c47c)
Solutions
- Use normalized relative paths as newBlobs keys (e.g. "docs/file.md", never "/docs/file.md" or "a/../b.md").
- Normalize or reject paths with GitUtils.normalizePath before inserting them into the map.
- Catch BlobEditException and report the offending path to the API caller.
- Validate file-name inputs at the UI/API boundary before constructing the commit payload.
Example fix
// before
new BlobEdits(Set.of(), Map.of("/new/file.txt", content)); // throws
// after
new BlobEdits(Set.of(), Map.of("new/file.txt", content)); Defensive patterns
Strategy: validation
Validate before calling
Map<String, BlobContent> safe = new LinkedHashMap<>();
for (var e : newBlobs.entrySet()) {
String n = GitUtils.normalizePath(e.getKey());
if (n == null) throw new IllegalArgumentException("Invalid new path: " + e.getKey());
safe.put(n, e.getValue());
} Type guard
boolean isValidNewPath(String p) {
return p != null && GitUtils.normalizePath(p) != null;
} Try / catch
try {
BlobEdits edits = new BlobEdits(oldPaths, newBlobs);
} catch (BlobEditException e) {
// return 400-style error naming the bad path
} Prevention
- Build new-file keys from validated file-name inputs only.
- Never accept keys starting with '/' or containing '..'.
- Normalize keys before inserting into newBlobs.
- Sanitize API payloads that carry file paths.
When it happens
Trigger: new BlobEdits(oldPaths, newBlobs) where a newBlobs map key is an invalid path (empty string, starts with '/', contains '..', or otherwise fails GitUtils.normalizePath).
Common situations: API clients committing files with absolute paths like "/README.md"; crafted requests attempting path traversal; UI forms submitting empty file names for new files; programmatic commits building paths by naive string concatenation.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- Invalid old path: <oldPath>
- Specified path is not a directory: ${blobIdent.path}
- 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
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/2feb3d88bda7211c.
Report an issue: GitHub.