{"record":{"id":"fd9d3089a449f5db","repo":"abhigyanpatwari/GitNexus","slug":"no-target-path-resolved","errorCode":null,"errorMessage":"No target path resolved","messagePattern":"No target path resolved","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/server/api.ts","lineNumber":1618,"sourceCode":"        (async () => {\n          let targetPath = repoLocalPath;\n          try {\n            // Clone if URL provided\n            if (repoUrl && !repoLocalPath) {\n              const repoName = extractWebRepoName(repoUrl);\n              targetPath = getCloneDir(repoName);\n\n              jobManager.updateJob(job.id, {\n                status: 'cloning',\n                repoName,\n                progress: { phase: 'cloning', percent: 0, message: `Cloning ${repoUrl}...` },\n              });\n\n              await cloneOrPull(\n                repoUrl,\n                targetPath,\n                (progress) => {\n                  jobManager.updateJob(job.id, {\n                    progress: { phase: progress.phase, percent: 5, message: progress.message },\n                  });\n                },\n                repoToken ? { token: repoToken } : undefined,\n              );\n            }\n\n            if (!targetPath) {\n              throw new Error('No target path resolved');\n            }\n\n            launchAnalysisWorker(job, targetPath, {\n              force,\n              embeddings,\n              dropEmbeddings,\n              springActuatorPath,\n              asyncApiSpecPath,\n            });","sourceCodeStart":1600,"sourceCodeEnd":1636,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/server/api.ts#L1600-L1636","documentation":"Defensive invariant in POST /api/analyze's async worker (api.ts ~1592): targetPath starts as the request's repoLocalPath and is only overwritten when a repoUrl clone runs. If both are falsy — request body carried neither a usable absolute 'path' nor a 'url' — the guard throws so the job is failed with a clear message instead of launching a worker against nothing.","triggerScenarios":"POST /api/analyze with an empty body {}, with path:'' and no url, or url:null — any combination that slips past earlier field checks yet leaves targetPath falsy when the worker starts.","commonSituations":"Client submits an unvalidated form where both fields are optional and both were left blank; a renamed API field ('repo' vs 'url') silently sending nothing; scripted calls with an empty JSON object.","solutions":["Include exactly one of: absolute filesystem 'path' or https/http 'url' ending in the repo name","Require at least one of the two fields in the client before submitting","Check the request body serialization (undefined values dropped by JSON.stringify)"],"exampleFix":"// before\nawait fetch('/api/analyze', { method: 'POST', body: JSON.stringify({}) });\n\n// after\nawait fetch('/api/analyze', {\n  method: 'POST',\n  body: JSON.stringify({ url: 'https://github.com/user/repo.git' }),\n});","handlingStrategy":"validation","validationCode":"function validAnalyzeBody(b) {\n  const hasUrl = typeof b.url === 'string' && b.url.trim().length > 0;\n  const hasPath = typeof b.path === 'string' && b.path.trim().length > 0;\n  return hasUrl !== hasPath; // exactly one\n}","typeGuard":"function isNonEmptyTargetSpec(b) {\n  return Boolean((typeof b?.url === 'string' && b.url) || (typeof b?.path === 'string' && b.path));\n}","tryCatchPattern":"// server-side job error carries 'No target path resolved'; treat as non-retryable client error\nif (job.error === 'No target path resolved') fixRequestBodyAndResubmit();","preventionTips":["Require exactly one of url/path in the client form","Beware JSON.stringify dropping undefined fields — default them explicitly","Add a pre-submit assert: !body.url && !body.path -> block submit"],"tags":["http-api","request-validation","job-failure"],"backgroundTag":"missing-required-argument","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}