{"record":{"id":"41de2fc483124abb","repo":"theonedev/onedev","slug":"branch-and-file-should-be-specified","errorCode":null,"errorMessage":"Branch and file should be specified","messagePattern":"Branch and file should be specified","errorType":"http","errorClass":"NotAcceptableException","httpStatus":406,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/RepositoryResource.java","lineNumber":393,"sourceCode":"\tpublic FileEditResponse editFile(\n\t\t\t@PathParam(\"projectId\") Long projectId, \n\t\t\t@PathParam(\"branchAndFile\") @NotEmpty @Api(example=\"test-branch/path/to/file\") String branchAndFile, \n\t\t\t@NotNull FileEditRequest request) {\n\t\tProject project = projectService.load(projectId);\n\t\t\n\t\tList<String> revisionAndPathSegments = Splitter.on('/').splitToList(branchAndFile);\n\t\tRevisionAndPath revisionAndPath;\n\t\tString refName;\n\t\tObjectId oldCommitId;\n\t\tif (project.getDefaultBranch() != null) {\n\t\t\trevisionAndPath = RevisionAndPath.parse(project, revisionAndPathSegments);\n\t\t\tRefFacade ref = project.getBranchRef(revisionAndPath.getRevision());\n\t\t\tif (ref == null) \n\t\t\t\tthrow new NotAcceptableException(\"Not a branch: \" + revisionAndPath.getRevision());\n\t\t\trefName = ref.getName();\n\t\t\toldCommitId = ref.getObjectId();\n\t\t\tif (revisionAndPath.getPath() == null)\n\t\t\t\tthrow new NotAcceptableException(\"Branch and file should be specified\");\n\t\t} else {\n\t\t\tif (revisionAndPathSegments.size() < 2)\n\t\t\t\tthrow new NotAcceptableException(\"Branch and file should be specified\");\n\t\t\trevisionAndPath = new RevisionAndPath(\n\t\t\t\t\trevisionAndPathSegments.get(0), \n\t\t\t\t\tStringUtils.join(revisionAndPathSegments.subList(1, revisionAndPathSegments.size())));\n\t\t\trefName = GitUtils.branch2ref(revisionAndPath.getRevision());\n\t\t\toldCommitId = ObjectId.zeroId();\n\t\t}\n\n\t\tif (!SecurityUtils.canModifyFile(project, revisionAndPath.getRevision(), revisionAndPath.getPath())) \n\t\t\tthrow new UnauthorizedException();\n\n\t\tMap<String, BlobContent> newBlobs = new HashMap<>();\n\t\t\n\t\tSet<String> oldPaths = new HashSet<>();\n\t\tif (!oldCommitId.equals(ObjectId.zeroId()) \n\t\t\t\t&& gitService.getMode(project, oldCommitId, revisionAndPath.getPath()) != 0) {","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/RepositoryResource.java#L375-L411","documentation":"RepositoryResource.editFile requires the 'revisionAndPath' parameter to contain both a revision and a file path. When the project has a default branch and the parsed RevisionAndPath has no path component — or when there are fewer than two path segments in the no-default-branch case — it throws a NotAcceptableException with message \"Branch and file should be specified\".","triggerScenarios":"Calling the file-edit endpoint with only a branch name and no file path (e.g. revisionAndPath = 'main' with no '/file' part), or with a single segment when no default branch is set.","commonSituations":"URL-encoding bugs that strip the path after the slash; scripts concatenating branch and path incorrectly; testing the endpoint with just a branch to probe behavior.","solutions":["Include both segments in the parameter: 'branch-name/path/to/file'.","Check that slashes in the path are not swallowed by your HTTP client or URL encoder.","When no default branch exists, ensure at least two segments (revision plus at least one path element) are supplied."],"exampleFix":"// before\ncurl -X PUT .../projects/42/files/main   // no file path\n\n// after\ncurl -X PUT .../projects/42/files/main/README.md","handlingStrategy":"validation","validationCode":"const segments = revisionAndPath.split(\"/\");\nif (segments.length < 2 || !segments.slice(1).join(\"/\")) {\n  throw new Error(\"revisionAndPath must be 'branch/path/to/file'\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  await editFile(projectId, revisionAndPath, changes);\n} catch (e) {\n  if (isNotAcceptable(e) && e.message === \"Branch and file should be specified\") {\n    // fix the URL: append the file path segment and retry\n  } else throw e;\n}","preventionTips":["Always build the parameter as 'branch/full/path/to/file'.","Watch for URL encoders/clients that drop or mangle slash-separated path segments.","Unit-test URL construction for the file-edit endpoint."],"tags":["rest-api","validation","git"],"backgroundTag":"missing-required-argument","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}