{"record":{"id":"af582fe55bc9d112","repo":"abhigyanpatwari/GitNexus","slug":"failed-to-start-analysis","errorCode":null,"errorMessage":"Failed to start analysis","messagePattern":"Failed to start analysis","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"gitnexus/src/server/api.ts","lineNumber":1611,"sourceCode":"              throw new Error('No target path resolved');\n            }\n\n            launchAnalysisWorker(job, targetPath, { force, embeddings, dropEmbeddings });\n          } catch (err: any) {\n            if (targetPath) releaseRepoLock(getStoragePath(targetPath));\n            jobManager.updateJob(job.id, {\n              status: 'failed',\n              error: err.message || 'Analysis failed',\n            });\n          }\n        })();\n\n        res.status(202).json({ jobId: job.id, status: job.status });\n      } catch (err: any) {\n        if (err.message?.includes('already in progress')) {\n          res.status(409).json({ error: err.message });\n        } else {\n          res.status(500).json({ error: err.message || 'Failed to start analysis' });\n        }\n      }\n    },\n  );\n\n  // POST /api/analyze/upload — analyze a browser folder upload.\n  // Securely ingests the multipart upload into a sandbox, promotes it to a\n  // persistent dir, and analyzes it via the shared job/worker machinery.\n  // localhost-only (no cross-origin write reach) + conservative rate limit.\n  app.post(\n    '/api/analyze/upload',\n    createRouteLimiter({ limit: 5 }),\n    requireTrustedOrigin,\n    createAnalyzeUploadHandler({\n      createJob: (params) => jobManager.createJob(params),\n      launch: (job, targetPath, opts) => launchAnalysisWorker(job, targetPath, opts),\n      failJob: (jobId, error) => jobManager.updateJob(jobId, { status: 'failed', error }),\n    }),","sourceCodeStart":1593,"sourceCodeEnd":1629,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/server/api.ts#L1593-L1629","documentation":"HTTP 500 returned by POST /api/analyze's outer catch when the synchronous part of the route throws anything other than an 'already in progress' conflict. The response forwards err.message when present and falls back to this literal string only when the error has no message — so seeing the exact text 'Failed to start analysis' means an anonymous/unexpected throw; the underlying error is available in the serve logs.","triggerScenarios":"An unexpected exception inside job creation or route setup (corrupted internal state, memory pressure, a GitNexus bug); an error object with an empty .message reaching the catch; anything the route's finer-grained 400 validations did not anticipate.","commonSituations":"Version skew between client expectations and an older serve build; disk-full or permission-broken storage making setup calls throw; rare post-upgrade bugs — the literal fallback text is the tell that message context was lost.","solutions":["Check the serve process output — the route and the global handler log the real error; the 500 body is intentionally vague","Reproduce with the exact body: any non-empty err.message replaces the literal text, which narrows the cause","Retry once after confirming no job is stuck (a stuck non-terminal job surfaces as 409 and can masquerade as 'cannot start')","If reproducible, update GitNexus and report the stack — a 500 here is by definition a server-side defect"],"exampleFix":"// before\nconst { jobId } = await res.json(); // opaque failure on 500\n\n// after\nif (res.status === 409) { /* adopt/poll the active job, see error 344 */ }\nelse if (res.status >= 500) { await backoffRetry(() => postAnalyze(body), 2); }\nelse if (!res.ok) throw new Error((await res.json()).error);","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"Branch on status at the fetch boundary: 409 → adopt/poll the active job; 5xx → retry the idempotent POST with exponential backoff (2-3 attempts); other 4xx → surface the forwarded error text to the caller.","preventionTips":["Check the serve log first — it has the detail the 500 body hides","Retry 5xx once or twice; transient setup failures usually clear","Keep serve and client on matched versions to avoid known start-path bugs"],"tags":["http-500","internal-error","job-scheduler","api"],"backgroundTag":"http-500-internal-server-error","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}