{"record":{"id":"05f2578f409d14c8","repo":"abhigyanpatwari/GitNexus","slug":"asyncapispecpath-must-be-a-non-empty-string","errorCode":null,"errorMessage":"\"asyncApiSpecPath\" must be a non-empty string","messagePattern":"\"asyncApiSpecPath\" must be a non-empty string","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"gitnexus/src/server/api.ts","lineNumber":1544,"sourceCode":"          res.status(400).json({ error: '\"url\" must be a string' });\n          return;\n        }\n        if (repoLocalPath !== undefined && typeof repoLocalPath !== 'string') {\n          res.status(400).json({ error: '\"path\" must be a string' });\n          return;\n        }\n        if (\n          springActuatorPath !== undefined &&\n          (typeof springActuatorPath !== 'string' || springActuatorPath.trim().length === 0)\n        ) {\n          res.status(400).json({ error: '\"springActuatorPath\" must be a non-empty string' });\n          return;\n        }\n        if (\n          asyncApiSpecPath !== undefined &&\n          (typeof asyncApiSpecPath !== 'string' || asyncApiSpecPath.trim().length === 0)\n        ) {\n          res.status(400).json({ error: '\"asyncApiSpecPath\" must be a non-empty string' });\n          return;\n        }\n\n        if (!repoUrl && !repoLocalPath) {\n          res.status(400).json({ error: 'Provide \"url\" (git URL) or \"path\" (local path)' });\n          return;\n        }\n\n        // Token: optional, restricted charset to prevent header smuggling\n        // (CRLF), bound length, and bound to github.com (see validateAnalyzeToken).\n        const tokenError = validateAnalyzeToken(repoToken, repoUrl);\n        if (tokenError) {\n          res.status(tokenError.status).json({ error: tokenError.error });\n          return;\n        }\n\n        // Path validation. The previous `normalize !== resolve` guard was inert\n        // (both collapse `..` identically) and only false-rejected trailing","sourceCodeStart":1526,"sourceCodeEnd":1562,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/server/api.ts#L1526-L1562","documentation":"The GitNexus HTTP API (createServer) validates the `asyncApiSpecPath` field in request bodies used to configure analysis targets. When the field is present but is not a string, or is an empty/whitespace-only string, the endpoint rejects the request with HTTP 400 and this message.","triggerScenarios":"Sending a POST request to the analyze/index endpoint whose JSON body includes `asyncApiSpecPath` set to null, a number, a boolean, an object, \"\" or \"   \" (whitespace only). The field being absent (undefined) passes validation.","commonSituations":"CLI or CI scripts templating an AsyncAPI spec path that resolves to empty; config files with `asyncApiSpecPath: \"\"` placeholders; JSON built programmatically where an unset option serializes as \"\".","solutions":["Omit `asyncApiSpecPath` from the request body if there is no AsyncAPI spec to analyze.","Provide a valid non-empty path string pointing at the AsyncAPI spec file.","Sanitize config before sending: map empty/blank values to undefined so the field is omitted.","Fix serialization so non-string values are not sent for this field."],"exampleFix":"// before\nconst body = { path: '.', asyncApiSpecPath: cfg.asyncApiSpecPath ?? '' };\n// after\nconst body = { path: '.', ...(cfg.asyncApiSpecPath ? { asyncApiSpecPath: cfg.asyncApiSpecPath } : {}) };","handlingStrategy":"validation","validationCode":"function validateAsyncApiSpecPath(v: unknown): string | undefined {\n  if (v === undefined) return undefined;\n  if (typeof v !== 'string' || v.trim().length === 0) throw new Error('asyncApiSpecPath must be a non-empty string');\n  return v;\n}","typeGuard":"function isValidOptionalString(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"const res = await fetch(url, { method: 'POST', body: JSON.stringify(payload) });\nif (res.status === 400) {\n  const { error } = await res.json();\n  if (error?.includes('asyncApiSpecPath')) {\n    delete payload.asyncApiSpecPath; // retry without the field\n  }\n}","preventionTips":["Omit optional path fields rather than sending empty strings.","Validate request bodies against a JSON schema (required: type string, minLength 1) before sending.","Coerce empty config values (\"\", null) to undefined at config-load time.","Centralize payload construction so optional fields are only included when set."],"tags":["http-api","validation","http-400"],"backgroundTag":"invalid-argument-value","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-09-08T00:40:44.970Z","contentChangedAt":"2026-09-08T00:40:44.970Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}