{"record":{"id":"7efe2cebfd18b120","repo":"abhigyanpatwari/GitNexus","slug":"invalid-gitnexus-fts-stemmer-process-env-gitnex","errorCode":null,"errorMessage":"Invalid GITNEXUS_FTS_STEMMER \"${process.env.GITNEXUS_FTS_STEMMER}\". Expected one of: ${[...SUPPORTED_FTS_STEMMERS].sort().join(', ')}.","messagePattern":"Invalid GITNEXUS_FTS_STEMMER \"(.+?)\"\\. Expected one of: (.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"gitnexus/src/core/search/fts-indexes.ts","lineNumber":171,"sourceCode":"  'swedish',\n  'tamil',\n  'turkish',\n]);\n\nexport interface CreateSearchFTSIndexesOptions {\n  onIndexStart?: (table: string, indexName: string) => void;\n  onIndexReady?: (table: string, indexName: string) => void;\n}\n\nlet resolvedStemmer: string | undefined;\n\n/** Read + validate `GITNEXUS_FTS_STEMMER`. Throws on an unsupported value. */\nfunction resolveFTSStemmer(): string {\n  const raw = process.env.GITNEXUS_FTS_STEMMER?.trim().toLowerCase();\n  if (!raw) return DEFAULT_FTS_STEMMER;\n  if (SUPPORTED_FTS_STEMMERS.has(raw)) return raw;\n\n  throw new Error(\n    `Invalid GITNEXUS_FTS_STEMMER \"${process.env.GITNEXUS_FTS_STEMMER}\". ` +\n      `Expected one of: ${[...SUPPORTED_FTS_STEMMERS].sort().join(', ')}.`,\n  );\n}\n\n/**\n * Resolve + validate `GITNEXUS_FTS_STEMMER` once, up front at analyze startup,\n * and cache it. An invalid value throws here — in milliseconds — instead of\n * ~85% into a run (after the expensive parse/scope-resolution work). The cached\n * value is what {@link getSearchFTSStemmer} returns for the rest of the run, so\n * config is read and validated in exactly one place.\n */\nexport function initialiseSearchFTSStemmer(): string {\n  resolvedStemmer = resolveFTSStemmer();\n  return resolvedStemmer;\n}\n\n/**","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/search/fts-indexes.ts#L153-L189","documentation":"Thrown by `resolveFTSStemmer()` when the `GITNEXUS_FTS_STEMMER` environment variable is set to a value not in `SUPPORTED_FTS_STEMMERS`. The supported set mirrors the stemmer tokens shipped by the LadybugDB FTS extension (28 values including `none`, `porter`, and language names like `english`, `french`). Validation runs once at startup via `initialiseSearchFTSStemmer()` and caches the result, so an invalid value fails in milliseconds instead of ~85% into a run after expensive parsing.","triggerScenarios":"`process.env.GITNEXUS_FTS_STEMMER` is set to any string not in the supported set (case-insensitive, after trimming). The `resolveFTSStemmer` function is called at analyze startup.","commonSituations":"Typo (`enlgish` instead of `english`); using a Porter stemmer variant name (`porter2`, `snowball`) that the extension doesn't recognize; using an uppercase value from copy-paste that happens to work elsewhere but not here (though this code lowercases); setting a language the extension version doesn't ship (after a LadybugDB downgrade).","solutions":["Set `GITNEXUS_FTS_STEMMER` to one of the supported values listed in the error message (e.g., `english`, `porter`, `none`).","Unset the variable to accept the default stemmer.","If using a language-specific stemmer, verify it's in the supported set — the error lists every accepted value sorted alphabetically."],"exampleFix":"# before\nexport GITNEXUS_FTS_STEMMER=enlgish\ngitnexus analyze\n# error: Invalid GITNEXUS_FTS_STEMMER \"enlgish\". Expected one of: arabic, basque, ...\n# after\nexport GITNEXUS_FTS_STEMMER=english\ngitnexus analyze","handlingStrategy":"validation","validationCode":"// Validate the env var before starting analyze:\nimport { SUPPORTED_FTS_STEMMERS } from './search/fts-indexes.js';\nconst raw = process.env.GITNEXUS_FTS_STEMMER?.trim().toLowerCase();\nif (raw && !SUPPORTED_FTS_STEMMERS.has(raw)) {\n  console.error(`Invalid stemmer. Supported: ${[...SUPPORTED_FTS_STEMMERS].sort().join(', ')}`);\n  process.exit(1);\n}","typeGuard":"import { SUPPORTED_FTS_STEMMERS } from './search/fts-indexes.js';\nconst isValidStemmer = (value: unknown): value is string =>\n  typeof value === 'string' && SUPPORTED_FTS_STEMMERS.has(value.trim().toLowerCase());","tryCatchPattern":"try {\n  await runAnalyze(options);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('Invalid GITNEXUS_FTS_STEMMER')) {\n    console.error('Check supported stemmers in the error message. Default is usually fine.');\n  }\n  throw err;\n}","preventionTips":["Import `SUPPORTED_FTS_STEMMERS` from `fts-indexes.ts` to validate in your own scripts.","When upgrading LadybugDB versions, re-check the supported stemmer set — it mirrors the extension's capabilities.","Unset the variable if you don't need a specific stemmer; the default is sensible."],"tags":["fts","config","env-var","stemmer","validation","search"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}