abhigyanpatwari/GitNexus · error
Missing "cypher" in request body
Error message
Missing "cypher" in request body
What it means
HTTP 400 from POST /api/query when req.body.cypher is falsy — undefined, null, or the empty string. The query endpoint requires a JSON body with a non-empty cypher string before it will resolve a repository and open the read-only LadybugDB connection. If instead you see a 500 with a TypeError message, your body was never parsed (missing Content-Type: application/json) — a different failure that this 400 is designed to preempt.
Source
Thrown at gitnexus/src/server/api.ts:651
res.status(404).json({ error: 'File not found' });
} else {
// statusFromError returns err.status for BadRequestError / ForbiddenError
// (assertString → 400 on array-form ?path=a&path=b; ForbiddenError → 403
// on traversal). Falls back to 500 for unrecognized failures.
res.status(statusFromError(err)).json({ error: err.message || 'Failed to read file' });
}
}
};
export const handleQueryRequest = async (
req: express.Request,
res: express.Response,
resolveRepo: (repoName?: string) => Promise<{ storagePath: string } | undefined>,
): Promise<void> => {
try {
const cypher = req.body.cypher as string;
if (!cypher) {
res.status(400).json({ error: 'Missing "cypher" in request body' });
return;
}
const queryParams = req.body.params;
if (queryParams !== undefined && !isValidQueryParams(queryParams)) {
res.status(400).json({
error: '"params" must be a plain object with scalar values (string/number/boolean/null)',
});
return;
}
const entry = await resolveRepo(requestedRepo(req));
if (!entry) {
res.status(404).json({ error: 'Repository not found' });
return;
}
const lbugPath = path.join(entry.storagePath, 'lbug');
const result = await withLbugDb(lbugPath, () => executePrepared(cypher, queryParams ?? {}), {
readOnly: true,View on GitHub (pinned to aac7515d2a)
Solutions
- Send JSON with the exact key: {"cypher": "MATCH (n) RETURN n LIMIT 5"} and header Content-Type: application/json
- Client-side, assert a non-empty string before issuing the request
- If you got a 500 mentioning 'cypher of undefined', your body was not parsed — set the content type
- Pass query values via the optional params object rather than string interpolation
Example fix
// before
await fetch(`${base}/api/query`, {
method: 'POST',
body: JSON.stringify({ query }), // wrong key → 400
});
// after
await fetch(`${base}/api/query`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ cypher: query, params: { limit: 5 } }),
}); Defensive patterns
Strategy: validation
Validate before calling
if (typeof cypher !== 'string' || cypher.trim() === '') throw new Error('cypher body field is required');
await fetch(`${base}/api/query`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ cypher }) }); Type guard
function isQueryBody(b: unknown): b is { cypher: string; params?: Record<string, string | number | boolean | null> } {
if (typeof b !== 'object' || b === null) return false;
const c = (b as Record<string, unknown>).cypher;
return typeof c === 'string' && c.length > 0;
} Prevention
- Use the exact body key 'cypher' (not query/statement)
- Set Content-Type: application/json so express.json actually parses the body
- Guard against empty templates producing cypher: ''
When it happens
Trigger: POSTing {} or {query: 'MATCH ...'} (wrong key — the key must be exactly cypher); sending cypher: '' for a 'run nothing' call; omitting the Content-Type header so express.json skips parsing and req.body stays unset; sending form-encoded instead of JSON.
Common situations: Copy-pasting a client for the /api/grep endpoint and forgetting the query API uses a different body key; API explorers defaulting to text/plain content type; code paths that build the body conditionally and skip the cypher field when a template is empty.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- "params" must be a plain object with scalar values (string/n
- "url" must be a string
- "path" must be a string
- Provide "url" (git URL) or "path" (local path)
- Missing path
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/dcf6c9819f60f1bc.
Report an issue: GitHub.