{"record":{"id":"f48fb4def00f31ba","repo":"abhigyanpatwari/GitNexus","slug":"understand-quickly-expected-id-of-the-form-owne","errorCode":null,"errorMessage":"[understand-quickly] expected id of the form \"owner/repo\", got \"${id}\". The registry uses this string to look up your entry in registry.json — it must match the GitHub owner/repo of the source code, not a local path.","messagePattern":"\\[understand-quickly\\] expected id of the form \"owner/repo\", got \"(.+?)\"\\. The registry uses this string to look up your entry in registry\\.json — it must match the GitHub owner/repo of the source code, not a local path\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"gitnexus-shared/src/integrations/understand-quickly.ts","lineNumber":51,"sourceCode":"export const UNDERSTAND_QUICKLY_TOKEN_ENV = 'UNDERSTAND_QUICKLY_TOKEN';\n\nexport interface UqDispatchPayload {\n  event_type: typeof UNDERSTAND_QUICKLY_EVENT_TYPE;\n  client_payload: {\n    /** `<owner>/<repo>` shape — must match the registered entry. */\n    id: string;\n  };\n}\n\n/**\n * Build the JSON body for the `repository_dispatch` ping. Pure — no\n * env reads, no network. Validates that `id` looks like `owner/repo`\n * (one slash, no whitespace, both halves non-empty) so a misconfigured\n * caller fails loudly before the round-trip.\n */\nexport function buildUqDispatchPayload(id: string): UqDispatchPayload {\n  if (!isValidOwnerRepo(id)) {\n    throw new Error(\n      `[understand-quickly] expected id of the form \"owner/repo\", got \"${id}\". ` +\n        `The registry uses this string to look up your entry in registry.json — ` +\n        `it must match the GitHub owner/repo of the source code, not a local path.`,\n    );\n  }\n  return {\n    event_type: UNDERSTAND_QUICKLY_EVENT_TYPE,\n    client_payload: { id },\n  };\n}\n\n/**\n * `owner/repo` validation. Conservative on purpose: GitHub's actual\n * naming rules are looser, but we want to catch local paths\n * (`/Users/...`), bare slugs (`my-repo`), and accidental whitespace.\n *\n * Matches GitHub's published slug rules:\n *   owner: starts with alnum, then alnum/hyphen only, must end with","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus-shared/src/integrations/understand-quickly.ts#L33-L69","documentation":"While acquiring the LadybugDB init lock, GitNexus found a lock whose owning PID is no longer alive, or whose timestamp is older than INIT_LOCK_STALE_MS (30 seconds). It unlinks the stale lock and returns true so the caller retries acquisition. This is self-healing crash recovery after an unclean shutdown, not an active failure.","triggerScenarios":"A previous analyzer process crashed (or was SIGKILLed) leaving the contentless init lock file behind; or a live-but-hung process held the lock past 30s, so it is treated as stale and reclaimed via fs.unlink(lockPath).","commonSituations":"CI jobs killed mid-analyze; a developer Ctrl-C'ing during init on Windows where cleanup handlers missed the lock; two analyzers pointed at the same storage dir where one died. The warn after a known crash is benign — the next acquire succeeds.","solutions":["No action needed after a known crash — the lock is reclaimed automatically and init proceeds","If it recurs without crashes, find what is holding locks >30s (hung process, antivirus file lock) in the storage directory","Avoid hard-killing analyzer processes (SIGKILL / taskkill /F); prefer SIGINT so cleanup handlers run","Ensure only one analyzer runs against a storage directory at a time"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import fs from 'node:fs/promises';\n// before acquiring: preemptively clear a lock whose owner is dead or older than 30s\nconst parsed = JSON.parse(await fs.readFile(lockPath, 'utf8').catch(() => 'null'));\nconst stale =\n  parsed === null ||\n  (typeof parsed.pid === 'number' && !isProcessAlive(parsed.pid)) ||\n  (typeof parsed.ts === 'number' && Date.now() - parsed.ts > 30_000);\nif (parsed !== null && stale) await fs.unlink(lockPath).catch(() => {});","typeGuard":"const isStaleLock = (parsed: unknown, staleMs = 30_000): boolean => {\n  if (typeof parsed !== 'object' || parsed === null) return true;\n  const { pid, ts } = parsed as { pid?: unknown; ts?: unknown };\n  if (typeof ts === 'number' && Date.now() - ts < staleMs && typeof pid === 'number' && isProcessAlive(pid)) return false;\n  return true;\n};","tryCatchPattern":null,"preventionTips":["Run a single analyzer per storage directory","Prefer SIGINT over SIGKILL so shutdown handlers remove locks","Treat this warn after a known crash as benign self-healing"],"tags":["ladybugdb","lock-file","crash-recovery"],"backgroundTag":"stale-lock-file","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}