{"record":{"id":"c998f8b0be8e8422","repo":"theonedev/onedev","slug":"unable-to-find-path-nonexistpath","errorCode":null,"errorMessage":"Unable to find path \" + nonExistPath","messagePattern":"Unable to find path \" \\+ nonExistPath","errorType":"exception","errorClass":"NotFoundException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/git/service/DefaultGitService.java","lineNumber":751,"sourceCode":"\t\t\t\t\t\t\t\t\tchildTreeWalk.enterSubtree();\n\t\t\t\t\t\t\t\t\tObjectId childTreeId = insertTree(revTree, childTreeWalk, inserter, treeWalk.getPathString(),\n\t\t\t\t\t\t\t\t\t\t\tchildOldPaths, childNewBlobs);\n\t\t\t\t\t\t\t\t\tif (childTreeId != null)\n\t\t\t\t\t\t\t\t\t\tentries.add(new TreeFormatterEntry(name, FileMode.TREE.getBits(), childTreeId));\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tthrow new NotTreeException(\"Path does not represent a tree: \" + treeWalk.getPathString());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tentries.add(new TreeFormatterEntry(name, treeWalk.getFileMode(0).getBits(), treeWalk.getObjectId(0)));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!currentOldPaths.isEmpty()) {\n\t\t\t\t\t\tString nonExistPath = currentOldPaths.iterator().next();\n\t\t\t\t\t\tif (parentPath != null)\n\t\t\t\t\t\t\tnonExistPath = parentPath + \"/\" + nonExistPath;\n\t\t\t\t\t\tthrow new NotFoundException(\"Unable to find path \" + nonExistPath);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!currentNewBlobs.isEmpty()) {\n\t\t\t\t\t\tSet<String> files = new HashSet<>();\n\t\t\t\t\t\tfor (Map.Entry<String, BlobContent> entry : currentNewBlobs.entrySet()) {\n\t\t\t\t\t\t\tString path = entry.getKey();\n\t\t\t\t\t\t\tif (!path.contains(\"/\")) {\n\t\t\t\t\t\t\t\tfiles.add(path);\n\t\t\t\t\t\t\t\tentries.add(new TreeFormatterEntry(path, entry.getValue().getMode(),\n\t\t\t\t\t\t\t\t\t\tinserter.insert(Constants.OBJ_BLOB, entry.getValue().getBytes())));\n\t\t\t\t\t\t\t\tfiles.add(path);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tSet<String> topLevelPathSegments = new LinkedHashSet<>();\n\t\t\t\t\t\tfor (String path : currentNewBlobs.keySet()) {\n\t\t\t\t\t\t\tif (path.contains(\"/\")) {\n\t\t\t\t\t\t\t\tString topLevelPathSegment = StringUtils.substringBefore(path, \"/\");\n\t\t\t\t\t\t\t\tif (files.contains(topLevelPathSegment)) {","sourceCodeStart":733,"sourceCodeEnd":769,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/git/service/DefaultGitService.java#L733-L769","documentation":"During a tree-writing operation in DefaultGitService (blob edits batched into a single commit), the code walks the existing tree matching the paths the caller wants to modify/delete. If some requested old paths were never matched against any existing tree entry, the tree does not contain them and a NotFoundException is thrown from insertTree. OneDev throws this so that blob-edit requests referencing non-existent files fail fast instead of silently producing a wrong commit.","triggerScenarios":"Calling the git service to update/delete blobs (BlobIdent old paths via BlobEdits / commitBlobEdits-style APIs) where at least one oldPath does not exist in the parent commit's tree, e.g. deleting a file that was already removed or editing a file at a misspelled path.","commonSituations":"Editing or deleting a file in a project via the web/API after another commit already deleted or renamed it; case-sensitivity mismatches (file renamed with different casing); stale client state attempting to delete an already-removed path; path typos in scripted API calls.","solutions":["Verify the path exists in the target commit before editing/deleting (list blobs of the commit or use getBlob).","Refresh your view/branch state — another commit may have removed or renamed the file; rebase or re-fetch.","Check path spelling and case exactly as stored in git (git ls-tree -r <commit>).","If the delete is idempotent by design, first check existence and skip the edit when the path is absent."],"exampleFix":"// before\ngitService.commitBlobEdits(projectId, refName, blobEdits, ...); // assumes file exists\n// after\nif (gitService.getBlobs(projectId, revision, blobEdits.getOldPaths()).size() != blobEdits.getOldPaths().size()) {\n    throw new ValidationException(\"One or more paths no longer exist on \" + refName);\n}\ngitService.commitBlobEdits(projectId, refName, blobEdits, ...);","handlingStrategy":"validation","validationCode":"Set<String> missing = blobEdits.getOldPaths().stream()\n    .filter(p -> gitService.getBlob(projectId, revision, p) == null)\n    .collect(Collectors.toSet());\nif (!missing.isEmpty()) throw new ValidationException(\"Paths not on \" + revision + \": \" + missing);","typeGuard":null,"tryCatchPattern":"try { gitService.commitBlobEdits(...); } catch (NotFoundException e) { log.warn(\"path vanished: {}\", e.getMessage()); refreshAndRetryOrSkip(); }","preventionTips":["Check path existence before batch edit/delete calls","Re-read ref state immediately before committing edits in multi-user repos","Match paths with exact case as stored in git"],"tags":["git","resource-not-found","path"],"backgroundTag":"resource-not-found","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}