{"record":{"id":"c7c5058f94043105","repo":"abhigyanpatwari/GitNexus","slug":"source-must-not-contain-markdown-significant-ch","errorCode":null,"errorMessage":"${source} must not contain Markdown-significant characters (` * [ ] < >).","messagePattern":"(.+?) must not contain Markdown-significant characters \\(` \\* \\[ \\] < >\\)\\.","errorType":"validation","errorClass":"GitNexusRcError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/cli/analyze-config.ts","lineNumber":245,"sourceCode":"      return validateBranchName(value, source);\n    case 'string': {\n      if (typeof value !== 'string') {\n        throw new GitNexusRcError(`${source} must be a string.`);\n      }\n      const trimmed = value.trim();\n      if (!trimmed) {\n        throw new GitNexusRcError(`${source} must not be empty.`);\n      }\n      assertNoHiddenChars(trimmed, source);\n      // `name` flows into the generated AGENTS.md/CLAUDE.md as `**${name}**` and\n      // inside `gitnexus://repo/${name}/…` code spans, so a Markdown-significant\n      // character would break those spans or inject emphasis/links/HTML into\n      // agent-instruction content (#1996 tri-review P1). `_` is intentionally\n      // allowed (legitimate in repo names; intraword `_` is not emphasis).\n      // embeddingDevice (the other `string`-kind option) only ever holds a\n      // fixed device token, so this guard never rejects a valid value there.\n      if (/[`*[\\]<>]/.test(trimmed)) {\n        throw new GitNexusRcError(\n          `${source} must not contain Markdown-significant characters (\\` * [ ] < >).`,\n        );\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();","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/cli/analyze-config.ts#L227-L263","documentation":"Thrown by normalizeValue() in the 'string' case when the trimmed value contains a Markdown-significant character: backtick, asterisk, [, ], <, or >. The 'name' value is interpolated into AGENTS.md/CLAUDE.md as **${name}** and inside gitnexus://repo/${name}/... code spans, so any of these characters could break the span or inject emphasis, links, or raw HTML into agent-instruction content. Underscore is intentionally allowed (legitimate in repo names and not emphasis mid-word). embeddingDevice only holds a fixed device token so this guard never rejects a valid device.","triggerScenarios":"Setting \"name\": \"my*repo\", \"name\": \"a[b]c\", \"name\": \"a<b>\", \"name\": \"a`b\", or \"name\": \"*>x\" in .gitnexusrc.","commonSituations":"A repo name containing glob-like characters; a paste that included markdown formatting; an attempt to set a name with angle brackets from a template; an adversarial config testing prompt injection.","solutions":["Use a repo name without Markdown-significant characters (letters, digits, '-', '_', '.').","If the real repo name contains such a character, choose a display alias for the config.","Audit the value for stray formatting copied from a rich-text source."],"exampleFix":"// before\n{ \"name\": \"my*repo`\" }\n\n// after\n{ \"name\": \"my-repo\" }","handlingStrategy":"validation","validationCode":"function assertNoMarkdownChars(value: string, key: string): void {\n  if (/[`*[\\]<>]/.test(value)) {\n    throw new Error(`${key} must not contain Markdown-significant characters`);\n  }\n}","typeGuard":"function isMarkdownSafe(value: unknown): value is string {\n  return typeof value === 'string' && !/[`*[\\]<>]/.test(value);\n}","tryCatchPattern":null,"preventionTips":["Keep repo/display names to letters, digits, '-', '_', and '.'.","Treat any Markdown-significant char in config as a potential prompt-injection vector.","Audit pasted values for stray formatting characters from rich-text sources."],"tags":["validation","markdown-injection","security","config"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}