abhigyanpatwari/GitNexus · error
"branch" must be a string
Error message
"branch" must be a string
What it means
A 400 validation response from the analyze endpoint: the optional `branch` field in the request body must be a string (an index-branch selector validated like the CLI's --branch flag). The server rejects non-string values before the ref can reach git.
Solutions
- Send branch as a JSON string: { "branch": "main" }
- Omit the branch field entirely instead of sending null
- Quote numeric-looking branch names in your request-building code or config
- Use the same branch value that works with the CLI's --branch flag
Example fix
// before
{ "repo": "my-repo", "branch": 123 }
// 400 { error: '"branch" must be a string' }
// after
{ "repo": "my-repo", "branch": "123-release" } Defensive patterns
Strategy: validation
Validate before calling
const isBranchOk = typeof branch === 'string' && branch.length > 0;
if (branch !== undefined && !isBranchOk) throw new Error('branch must be a string'); Type guard
const isString = (v: unknown): v is string => typeof v === 'string';
if (branch !== undefined && !isString(branch)) throw new TypeError('"branch" must be a string'); Prevention
- Quote numeric-looking branch names when building requests from configs/YAML
- Omit branch instead of sending null or placeholders
- Type-check request bodies at the boundary (zod/ajv schema with branch: string optional)
When it happens
Trigger: POST to the analyze route with body { branch: 123 }, { branch: true }, { branch: null } (treated as non-undefined), or any other non-string type.
Common situations: Happens when clients build the JSON body dynamically (e.g. number-like branch names '123' parsed as numbers by YAML/JSON tooling), or a template sends a null placeholder instead of omitting the field.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- "asyncApiSpecPath" must be a non-empty string
- contains characters not allowed in a git ref
- Missing "cypher" in request body
- Missing path
- must not be empty
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/8fac045b3123fb7a.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/server/api.ts:1752
if (
asyncApiSpecPath !== undefined &&
(typeof asyncApiSpecPath !== 'string' || asyncApiSpecPath.trim().length === 0)
) {
res.status(400).json({ error: '"asyncApiSpecPath" must be a non-empty string' });
return;
}
if (!repoUrl && !repoLocalPath) {
res.status(400).json({ error: 'Provide "url" (git URL) or "path" (local path)' });
return;
}
// Branch: optional index-branch selector, validated with the same rules
// as the CLI's `--branch` so both entry points accept the same refs.
// Rejecting here (rather than letting the clone fail) keeps a malformed
// ref from ever reaching `git`.
if (repoBranch !== undefined && typeof repoBranch !== 'string') {
res.status(400).json({ error: '"branch" must be a string' });
return;
}
let analyzeBranch: string | undefined;
if (repoBranch !== undefined) {
try {
analyzeBranch = validateBranchName(repoBranch, '"branch"');
} catch (err) {
if (err instanceof InvalidBranchError) {
res.status(400).json({ error: err.message });
return;
}
throw err;
}
}
// Token: optional, restricted charset to prevent header smuggling
// (CRLF), bound length, and bound to github.com (see validateAnalyzeToken).
const tokenError = validateAnalyzeToken(repoToken, repoUrl);View on GitHub (pinned to ac9a4e9abd)