{"record":{"id":"88589f6827e249e8","repo":"abhigyanpatwari/GitNexus","slug":"source-must-be-a-string-branch-name","errorCode":null,"errorMessage":"${source} must be a string branch name.","messagePattern":"(.+?) must be a string branch name\\.","errorType":"validation","errorClass":"GitNexusRcError","httpStatus":null,"severity":"warning","filePath":"gitnexus/src/cli/analyze-config.ts","lineNumber":204,"sourceCode":"  }\n}\n\nconst normalizeValue = (kind: ValueKind, value: unknown, key: string): unknown => {\n  const source = `${GITNEXUS_RC_FILENAME} \"${key}\"`;\n  switch (kind) {\n    case 'boolean':\n      if (typeof value !== 'boolean') {\n        throw new GitNexusRcError(`${source} must be a boolean (true/false).`);\n      }\n      return value;\n    case 'boolean-negate':\n      if (typeof value !== 'boolean') {\n        throw new GitNexusRcError(`${source} must be a boolean (true/false).`);\n      }\n      return !value;\n    case 'branch':\n      if (typeof value !== 'string') {\n        throw new GitNexusRcError(`${source} must be a string branch name.`);\n      }\n      return validateBranchName(value, source);\n    case 'path': {\n      if (typeof value !== 'string') {\n        throw new GitNexusRcError(`${source} must be a file or directory path.`);\n      }\n      const trimmed = value.trim();\n      if (!trimmed) {\n        throw new GitNexusRcError(`${source} must not be empty.`);\n      }\n      assertNoHiddenChars(trimmed, source);\n      return trimmed;\n    }\n    case 'string': {\n      if (typeof value !== 'string') {\n        throw new GitNexusRcError(`${source} must be a string.`);\n      }\n      const trimmed = value.trim();","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/cli/analyze-config.ts#L186-L222","documentation":"Rate-limited sidecar-recovery logging: warnOnce warns on the first occurrence of a condition key and again only at milestone counts (WARN_MILESTONES = [1, 10, 100, 1000, 10000]); non-milestone repeats drop to debug. This message shape — base message plus '(Nth occurrence of this condition)' — means the identical recovery condition has now recurred N times in this process. The underlying conditions are LadybugDB sidecar/WAL recovery events keyed per cause (e.g. the LADYBUGDB-CONTRACT missing-shadow error text, keyed on the locale-invariant Win32 code 2 for Windows).","triggerScenarios":"warnedKeyCounts.get(key) hits a milestone — the same recovery path (missing .shadow sidecar detection, quarantine, rename) fires repeatedly, e.g. every DB open finding the same missing-shadow condition, or a crash loop reopening the store.","commonSituations":"Persistent crash-then-reopen cycles (CI killing analyze); a storage directory where AV keeps removing/locking shadow sidecars; non-English Windows installs where error matching relies on the invariant error code rather than localized text (issue #2382). The ordinal tells you whether you have a one-off (1st) or a systematic condition (100th).","solutions":["Use the ordinal to gauge severity: 1st occurrence after a crash is expected; 10th+ means a systematic condition","Identify the base condition in the same log line (the message before the parenthetical) and fix its cause — e.g. stop the crash loop, exclude storage dir from AV","Run `gitnexus clean` and a fresh full analyze to reset sidecar state","If the base message mentions shadow-sidecar errors, verify LadybugDB version compatibility (LADYBUGDB-CONTRACT comments in sidecar-recovery.ts)"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"import fs from 'node:fs/promises';\n// before open: detect the missing-shadow precondition that feeds this recovery path\nconst shadowExists = await fs.access(`${dbPath}.shadow`).then(() => true, () => false);\nconst walExists = await fs.access(`${dbPath}.wal`).then(() => true, () => false);\nif (walExists && !shadowExists) {\n  // a recovery event is likely on open — back up / investigate before proceeding\n}","typeGuard":"// LADYBUGDB-CONTRACT shape: native missing-shadow error, locale-invariant on Windows\nconst isMissingShadowError = (e: unknown): e is Error =>\n  e instanceof Error && /Cannot open file.*\\.shadow/.test(e.message);","tryCatchPattern":"try {\n  await openDb(dbPath);\n} catch (e) {\n  if (isMissingShadowError(e)) {\n    // sidecar recovery will quarantine + rename the WAL; let it run, then reopen\n    return openDb(dbPath);\n  }\n  throw e;\n}","preventionTips":["Use the occurrence ordinal as a recurrence meter — 10th+ means fix the systematic cause, not the symptom","Exclude the storage directory from AV so shadow sidecars are not removed mid-checkpoint","Re-validate LADYBUGDB-CONTRACT error matching whenever bumping the LadybugDB version"],"tags":["sidecar","wal","log-throttling","ladybugdb"],"backgroundTag":"missing-shadow-sidecar","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-09-01T13:15:02.810Z","contentChangedAt":"2026-09-01T13:15:02.810Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}