{"record":{"id":"d433d77d96de68a5","repo":"theonedev/onedev","slug":"either-commit-hash-branch-or-tag-should-be-specif","errorCode":null,"errorMessage":"Either commit hash, branch or tag should be specified","messagePattern":"Either commit hash, branch or tag should be specified","errorType":"exception","errorClass":"io.onedev.server.exception.NotAcceptableException","httpStatus":406,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/ai/TodResource.java","lineNumber":1709,"sourceCode":"\n        if (!SecurityUtils.canRunJob(subject, project, jobName))\t\t\n            throw new UnauthorizedException();\n\n        String refName;\n        var branch = trimToNull((String)data.get(\"branch\"));\n        var tag = trimToNull((String)data.get(\"tag\"));\n        var commitHash = trimToNull((String)data.get(\"commitHash\"));\n        if (commitHash != null) {\n            refName = trimToNull((String)data.get(\"refName\"));\n            if (refName == null) {\n                throw new NotAcceptableException(\"Ref name is required when commit hash is specified\");\n            }\n        } else if (branch != null) {            \n            refName = GitUtils.branch2ref(branch);\n        } else if (tag != null) {\n            refName = GitUtils.tag2ref(tag);\n        } else {\n            throw new NotAcceptableException(\"Either commit hash, branch or tag should be specified\");\n        }\n        if (commitHash == null)\n            commitHash = project.getRevCommit(refName, true).name();\n            \n        Map<String, List<String>> params;\n        var paramData = data.get(\"params\");\n        if (paramData instanceof List) {\n            params = new HashMap<String, List<String>>();\n            List<String> paramPairs = (List<String>) paramData;\n            if (paramPairs != null) {\n                for (var paramPair: paramPairs) {\n                    var paramName = trimToNull(StringUtils.substringBefore(paramPair, \"=\"));\n                    var paramValue = trimToNull(StringUtils.substringAfter(paramPair, \"=\"));\n                    if (paramName != null && paramValue != null)\n                        params.computeIfAbsent(paramName, k -> new ArrayList<>()).add(paramValue);\n                }\n            }\n        } else if (paramData instanceof Map) {","sourceCodeStart":1691,"sourceCodeEnd":1727,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/ai/TodResource.java#L1691-L1727","documentation":"TodResource requires a way to determine which revision to build. If none of commitHash, branch, or tag is present in the submitted data, it throws NotAcceptableException because it cannot resolve a refName or commit for jobService.submit.","triggerScenarios":"Calling the job-submit tool endpoint where data.get(\"commitHash\"), data.get(\"branch\"), and data.get(\"tag\") are all null/blank.","commonSituations":"AI agents constructing the submit payload from scratch and omitting all revision fields; callers assuming a default branch is used automatically (OneDev has no such default here).","solutions":["Include at least one of 'branch', 'tag', or 'commitHash' (with 'refName') in the request data.","For typical CI runs pass the branch: data.put(\"branch\", \"main\").","Check your tool-call payload generation to ensure revision fields are not stripped or trimmed to null."],"exampleFix":"// before\nvar data = new HashMap<String, Serializable>();\ndata.put(\"jobName\", \"ci\");\n// after\nvar data = new HashMap<String, Serializable>();\ndata.put(\"jobName\", \"ci\");\ndata.put(\"branch\", \"main\");","handlingStrategy":"validation","validationCode":"const revisionFields = [data.commitHash, data.branch, data.tag].filter(v => v && String(v).trim());\nif (revisionFields.length === 0) throw new Error(\"One of commitHash, branch or tag is required\");","typeGuard":"function hasRevision(d) { return [\"commitHash\",\"branch\",\"tag\"].some(k => typeof d[k] === \"string\" && d[k].trim().length > 0); }","tryCatchPattern":"try { submit(data); } catch (e) { if (e.status === 406 && /branch or tag should be specified/.test(e.message)) { data.branch = defaultBranch; return submit(data); } throw e; }","preventionTips":["Always default to the repository's default branch when no revision is known","Validate payload completeness with a schema before calling the endpoint","Never send submit requests with all revision fields empty"],"tags":["missing-required-parameter","rest-api","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-14T05:17:10.506Z"}