{"record":{"id":"8eab48b20b7e92a1","repo":"abhigyanpatwari/GitNexus","slug":"source-value-contains-control-or-hidden-bidire","errorCode":null,"errorMessage":"${source}: value contains control or hidden/bidirectional characters, which are not allowed.","messagePattern":"(.+?): value contains control or hidden/bidirectional characters, which are not allowed\\.","errorType":"validation","errorClass":"GitNexusRcError","httpStatus":null,"severity":"warning","filePath":"gitnexus/src/cli/analyze-config.ts","lineNumber":152,"sourceCode":" * Reject control characters and hidden / bidirectional Unicode in a string\n * value. These have no legitimate place in a branch name, registry name, or\n * device string, and would otherwise let a committed config smuggle invisible\n * controls into generated AGENTS.md / CLAUDE.md content.\n */\nconst isHiddenOrControl = (codePoint: number): boolean =>\n  codePoint < 0x20 ||\n  codePoint === 0x7f ||\n  (codePoint >= 0x200b && codePoint <= 0x200f) || // zero-width + LRM/RLM\n  (codePoint >= 0x202a && codePoint <= 0x202e) || // bidi embeddings/overrides\n  (codePoint >= 0x2060 && codePoint <= 0x2064) || // word-joiner + invisible math\n  (codePoint >= 0x2066 && codePoint <= 0x206f) || // bidi isolates + deprecated\n  codePoint === 0xfeff; // BOM / zero-width no-break space\n\nconst assertNoHiddenChars = (value: string, source: string): void => {\n  for (const ch of value) {\n    const cp = ch.codePointAt(0);\n    if (cp !== undefined && isHiddenOrControl(cp)) {\n      throw new GitNexusRcError(\n        `${source}: value contains control or hidden/bidirectional characters, which are not allowed.`,\n      );\n    }\n  }\n};\n\n/**\n * Validate a user-supplied branch name (from CLI or `.gitnexusrc`). Returns the\n * trimmed name or throws {@link GitNexusRcError}. Rules live in\n * `core/git-ref.ts`; this wrapper keeps the CLI / `.gitnexusrc` error type.\n */\nexport function validateBranchName(value: string, source: string): string {\n  try {\n    return validateBranchNameCore(value, source);\n  } catch (err) {\n    if (err instanceof InvalidBranchError) {\n      throw new GitNexusRcError(err.message);\n    }","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/cli/analyze-config.ts#L134-L170","documentation":"On DB open, GitNexus found WAL files that LadybugDB had quarantined (renamed to `${dbPath}.wal.missing-shadow.<ts>-<rand>` by quarantineWalForMissingShadow) after an unrecoverable prior crash, and deleted them. Quarantined WALs are permanently detached from the live store and never reopened, so removal is safe regardless of whether the main DB exists. A reclaim failure (e.g. transient EBUSY from antivirus) never blocks DB startup.","triggerScenarios":"cleanQuarantinedMissingShadowWals(dbPath) returns files matching the quarantine rename pattern — i.e. a previous run crashed in a way where the WAL's shadow sidecar was missing and LadybugDB could not recover, so it set the WAL aside instead of deleting it.","commonSituations":"Power loss or forced kill during heavy write load (the #1618-style crash loop); antivirus quarantining or locking a .shadow sidecar mid-checkpoint so the next open finds the WAL unrecoverable; repeated occurrences point at systematic crash-then-recover cycles on the same machine.","solutions":["Treat a single occurrence after a crash as expected recovery — no action required","If it repeats, capture why runs crash in the first place (OOM, SIGKILL, disk full) and fix that root cause","Add the GitNexus storage directory to antivirus exclusions so sidecars are not locked/removed mid-run","Run `gitnexus clean` and re-index if you suspect accumulated crash debris in the storage dir"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"import fs from 'node:fs/promises';\nimport path from 'node:path';\n// before opening the DB: detect leftover quarantines from a prior crash\nconst dir = path.dirname(dbPath);\nconst quarantined = (await fs.readdir(dir).catch(() => []))\n  .filter((f) => f.includes('.wal.missing-shadow.'));\nif (quarantined.length > 0) {\n  // expect reclaim warns on open; investigate what crashed the previous run\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Fix the root cause of crashes (OOM, forced kills) rather than relying on reclaim","Exclude the storage directory from antivirus so sidecars are not locked mid-run","Run `gitnexus clean` before a fresh full re-index to clear accumulated crash debris"],"tags":["ladybugdb","wal","crash-recovery"],"backgroundTag":"wal-crash-recovery","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}