{"record":{"id":"1be30bcbe124cd73","repo":"abhigyanpatwari/GitNexus","slug":"source-entries-must-not-be-empty","errorCode":null,"errorMessage":"${source} entries must not be empty.","messagePattern":"(.+?) entries must not be empty\\.","errorType":"validation","errorClass":"GitNexusRcError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/cli/analyze-config.ts","lineNumber":255,"sourceCode":"        );\n      }\n      return trimmed;\n    }\n    case 'string-array': {\n      // Generic shared validator — `source` already names the config key, so\n      // messages here stay key-agnostic (no fetch-wrapper coupling in the\n      // shared normalizer; #1589/#1852 review F7).\n      if (!Array.isArray(value)) {\n        throw new GitNexusRcError(`${source} must be an array of strings.`);\n      }\n      const names: string[] = [];\n      for (const item of value) {\n        if (typeof item !== 'string') {\n          throw new GitNexusRcError(`${source} entries must all be strings.`);\n        }\n        const trimmed = item.trim();\n        if (!trimmed) {\n          throw new GitNexusRcError(`${source} entries must not be empty.`);\n        }\n        assertNoHiddenChars(trimmed, source);\n        // Values may be interpolated into a RegExp downstream. Restrict to\n        // identifier / member-access shapes so a config value can never smuggle\n        // regex metacharacters into a consumer.\n        if (!/^[A-Za-z_$][A-Za-z0-9_$.]*$/.test(trimmed)) {\n          throw new GitNexusRcError(\n            `${source} entry \"${trimmed}\" must be an identifier or member name ` +\n              `(letters, digits, _, $, . — e.g. \"client.get\").`,\n          );\n        }\n        names.push(trimmed);\n      }\n      if (names.length === 0) {\n        throw new GitNexusRcError(`${source} must list at least one string.`);\n      }\n      // De-duplicate and cap to a sane bound so a pathological config cannot\n      // blow up the consumer scan's alternation.","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/cli/analyze-config.ts#L237-L273","documentation":"The .gitnexusrc string-array validator trims each element of 'fetchWrappers' and throws when an element is empty after trimming. Empty names cannot map to any function wrapper, so the shared normalizer rejects them instead of silently skipping.","triggerScenarios":"{\"fetchWrappers\": [\"client.get\", \"   \"]} or an explicit \"\" element, at the flat level or inside the nested \"analyze\" object.","commonSituations":"Leaving a placeholder entry (\"\" or \"TODO\") in a committed .gitnexusrc; merge artifacts that leave a stray comma-separated empty slot; copy-paste from docs that include an empty example element.","solutions":["Remove or fill in the blank entry so every element trims to a non-empty identifier","Confirm with a quick check: every element matches /^[A-Za-z_$][A-Za-z0-9_$.]*$/ after trim","Add a pre-commit or CI hook that rejects empty strings in fetchWrappers"],"exampleFix":"// before (.gitnexusrc)\n{\"fetchWrappers\": [\"client.get\", \"\"]}\n// after\n{\"fetchWrappers\": [\"client.get\"]}","handlingStrategy":"validation","validationCode":"const fw = rc.fetchWrappers ?? [];\nif (fw.some((x: string) => x.trim() === '')) {\n  throw new Error('fetchWrappers contains an empty entry');\n}","typeGuard":"const hasNoBlankEntries = (v: string[]): boolean =>\n  v.every((x) => x.trim().length > 0);","tryCatchPattern":"catch (err) {\n  if (err instanceof GitNexusRcError && err.message.includes('must not be empty')) {\n    // point the user at the blank entry in their rc file\n  }\n}","preventionTips":["Filter blanks before serializing: names.filter((n) => n.trim())","In templates, skip empty variables instead of rendering an empty string entry"],"tags":["config","validation","gitnexusrc"],"backgroundTag":"empty-config-value","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"}