{"record":{"id":"95c5b0d1749e92b4","repo":"abhigyanpatwari/GitNexus","slug":"invalid-gitnexus-fts-cjk-segmentation-process-e","errorCode":null,"errorMessage":"Invalid GITNEXUS_FTS_CJK_SEGMENTATION \"${process.env.GITNEXUS_FTS_CJK_SEGMENTATION}\". Expected one of: ${[...SUPPORTED_FTS_CJK_SEGMENTATION_MODES].sort().join(', ')}.","messagePattern":"Invalid GITNEXUS_FTS_CJK_SEGMENTATION \"(.+?)\"\\. Expected one of: (.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"gitnexus/src/core/search/cjk-segmentation.ts","lineNumber":149,"sourceCode":" * interpolate a persisted `RepoMeta.cjkSegmentation` value into agent-visible\n * text (e.g. the MCP query-tool's mode-drift warning, #2339) must validate\n * with this first — that field comes from `meta.json`, a schema-less\n * `JSON.parse` of on-disk state inside the analyzed repo, not a trusted\n * input, so an unvalidated value could otherwise be echoed verbatim into\n * tool output an agent is expected to trust and act on.\n */\nexport const isSupportedCjkSegmentationMode = (value: unknown): value is string =>\n  typeof value === 'string' && SUPPORTED_FTS_CJK_SEGMENTATION_MODES.has(value);\n\nlet resolvedCjkSegmentation: string | undefined;\n\n/** Read + validate `GITNEXUS_FTS_CJK_SEGMENTATION`. Throws on an unsupported value. */\nfunction resolveFTSCjkSegmentation(): string {\n  const raw = process.env.GITNEXUS_FTS_CJK_SEGMENTATION?.trim().toLowerCase();\n  if (!raw) return DEFAULT_FTS_CJK_SEGMENTATION;\n  if (SUPPORTED_FTS_CJK_SEGMENTATION_MODES.has(raw)) return raw;\n\n  throw new Error(\n    `Invalid GITNEXUS_FTS_CJK_SEGMENTATION \"${process.env.GITNEXUS_FTS_CJK_SEGMENTATION}\". ` +\n      `Expected one of: ${[...SUPPORTED_FTS_CJK_SEGMENTATION_MODES].sort().join(', ')}.`,\n  );\n}\n\n/**\n * Resolve + validate `GITNEXUS_FTS_CJK_SEGMENTATION` once, up front at analyze\n * startup, and cache it — mirrors `initialiseSearchFTSStemmer` so an invalid\n * value fails in milliseconds instead of partway through a run. The cached\n * value is what {@link getSearchFTSCjkSegmentation} returns for the rest of\n * the run, so config is read and validated in exactly one place.\n */\nexport function initialiseSearchFTSCjkSegmentation(): string {\n  resolvedCjkSegmentation = resolveFTSCjkSegmentation();\n  return resolvedCjkSegmentation;\n}\n\n/**","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/search/cjk-segmentation.ts#L131-L167","documentation":"Thrown by `resolveFTSCjkSegmentation()` when the `GITNEXUS_FTS_CJK_SEGMENTATION` environment variable is set to a value not in the supported set (`none`, `bigram`). Validation happens once at analyze startup and caches the result, so an invalid value fails in milliseconds rather than partway through a run. The value is lowercased and trimmed before comparison, so only the two exact lowercase tokens are accepted.","triggerScenarios":"`process.env.GITNEXUS_FTS_CJK_SEGMENTATION` is set to any string other than `none` or `bigram` (case-insensitive, after trimming). The `resolveFTSCjkSegmentation` function is called at analyze startup via the initialization path.","commonSituations":"Typo in the env var (`bigrams` instead of `bigram`); copied a value from documentation for a different library (e.g., `jieba`, which is deliberately excluded because it crashes the process); set the value to `true` or `1` thinking it's a boolean flag.","solutions":["Set `GITNEXUS_FTS_CJK_SEGMENTATION` to either `none` (default, no CJK segmentation) or `bigram` (overlapping character bigrams for CJK search).","Unset the variable entirely to accept the default (`none`).","Check for typos: the value is case-insensitive but must be exactly one of the two supported tokens."],"exampleFix":"# before\nexport GITNEXUS_FTS_CJK_SEGMENTATION=jieba\ngitnexus analyze\n# error: Invalid GITNEXUS_FTS_CJK_SEGMENTATION \"jieba\". Expected one of: bigram, none.\n# after\nexport GITNEXUS_FTS_CJK_SEGMENTATION=bigram\ngitnexus analyze","handlingStrategy":"validation","validationCode":"// Validate the env var before starting analyze:\nconst SUPPORTED = new Set(['none', 'bigram']);\nconst raw = process.env.GITNEXUS_FTS_CJK_SEGMENTATION?.trim().toLowerCase();\nif (raw && !SUPPORTED.has(raw)) {\n  console.error(`Invalid GITNEXUS_FTS_CJK_SEGMENTATION. Use one of: ${[...SUPPORTED].join(', ')}`);\n  process.exit(1);\n}","typeGuard":"import { isSupportedCjkSegmentationMode } from './search/cjk-segmentation.js';\n// isSupportedCjkSegmentationMode is exported and usable as a type guard:\nconst value: unknown = process.env.GITNEXUS_FTS_CJK_SEGMENTATION;\nif (typeof value === 'string' && isSupportedCjkSegmentationMode(value)) {\n  // safe to use\n}","tryCatchPattern":"try {\n  await runAnalyze(options);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('Invalid GITNEXUS_FTS_CJK_SEGMENTATION')) {\n    console.error('Set GITNEXUS_FTS_CJK_SEGMENTATION to \"none\" or \"bigram\", or unset it.');\n  }\n  throw err;\n}","preventionTips":["Use the exported `isSupportedCjkSegmentationMode` type guard to validate before setting the env var in scripts.","Remember only `none` and `bigram` are supported — `jieba` is deliberately excluded."],"tags":["fts","config","env-var","cjk","validation","search"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}