{"record":{"id":"d8ac4c330ba4b201","repo":"badges/shields","slug":"field-idsuffix-must-contain-only-numbers-letter","errorCode":null,"errorMessage":"Field `idSuffix` must contain only numbers, letters, -, and _","messagePattern":"Field `idSuffix` must contain only numbers, letters, -, and _","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"badge-maker/lib/index.js","lineNumber":55,"sourceCode":"        }\n      })\n    }\n  }\n\n  const styleValues = [\n    'plastic',\n    'flat',\n    'flat-square',\n    'for-the-badge',\n    'social',\n  ]\n  if ('style' in format && !styleValues.includes(format.style)) {\n    throw new ValidationError(\n      `Field \\`style\\` must be one of (${styleValues.toString()})`,\n    )\n  }\n  if ('idSuffix' in format && !/^[a-zA-Z0-9\\-_]*$/.test(format.idSuffix)) {\n    throw new ValidationError(\n      'Field `idSuffix` must contain only numbers, letters, -, and _',\n    )\n  }\n}\n\nfunction _clean(format) {\n  const expectedKeys = [\n    'label',\n    'message',\n    'labelColor',\n    'color',\n    'style',\n    'logoBase64',\n    'links',\n    'idSuffix',\n  ]\n\n  const cleaned = {}","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/badges/shields/blob/766fd8bc89a90b8534dc573ab72dec30215ab1ec/badge-maker/lib/index.js#L37-L73","documentation":"The optional `idSuffix` field (used to disambiguate SVG element IDs when several badges appear on the same page) must match /^[a-zA-Z0-9\\-_]*$/ — only letters, numbers, hyphens, and underscores. _validate enforces this (badge-maker/lib/index.js:54) because the value is embedded in generated SVG IDs/markup and must be safe.","triggerScenarios":"makeBadge({ message: 'x', idSuffix: 'badge #1' }), idSuffix: 'a.b', idSuffix: 'id/2', or any value containing spaces, dots, slashes, or other special characters.","commonSituations":"Using numeric counters with formatting (e.g. '1.0'), passing filenames or URLs as the suffix, or generating ids from untrusted/user input containing arbitrary characters.","solutions":["Sanitize the suffix: idSuffix: raw.replace(/[^a-zA-Z0-9\\-_]/g, '-')","Use simple counters or slugs: idSuffix: String(index) or slugified names","Omit idSuffix entirely if you render only one badge per page"],"exampleFix":"// before\nconst svg = makeBadge({ message: 'v1.0', idSuffix: `badge ${name}` })\n// after\nconst svg = makeBadge({ message: 'v1.0', idSuffix: `badge-${name}`.replace(/[^a-zA-Z0-9\\-_]/g, '-') })","handlingStrategy":"validation","validationCode":"if ('idSuffix' in badge && !/^[a-zA-Z0-9\\-_]*$/.test(badge.idSuffix)) {\n  badge.idSuffix = badge.idSuffix.replace(/[^a-zA-Z0-9\\-_]/g, '-')\n}\nconst svg = makeBadge(badge)","typeGuard":"function isValidIdSuffix(v) {\n  return typeof v === 'string' && /^[a-zA-Z0-9\\-_]*$/.test(v)\n}","tryCatchPattern":"try {\n  return makeBadge(badge)\n} catch (e) {\n  if (e instanceof ValidationError && e.message.includes('idSuffix')) {\n    return makeBadge({ ...badge, idSuffix: badge.idSuffix.replace(/[^a-zA-Z0-9\\-_]/g, '-') })\n  }\n  throw e\n}","preventionTips":["Use plain counters or slugs as idSuffix values","Sanitize any user-derived string before assigning it","Omit idSuffix when rendering a single badge per page"],"tags":["validation","regex","sanitization"],"backgroundTag":"invalid-identifier-format","analyzedSha":"766fd8bc89a90b8534dc573ab72dec30215ab1ec","analyzedAt":"2026-08-30T01:40:27.499Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}