{"record":{"id":"6e28f00889d4e88a","repo":"vercel/ai","slug":"the-separator-separator-must-not-be-part-of-t","errorCode":null,"errorMessage":"The separator \"${separator}\" must not be part of the alphabet \"${alphabet}\".","messagePattern":"The separator \"(.+?)\" must not be part of the alphabet \"(.+?)\"\\.","errorType":"validation","errorClass":"InvalidArgumentError","httpStatus":null,"severity":"error","filePath":"packages/provider-utils/src/generate-id.ts","lineNumber":39,"sourceCode":"  size?: number;\n  alphabet?: string;\n} = {}): IdGenerator => {\n  const generator = () => {\n    const alphabetLength = alphabet.length;\n    const chars = new Array(size);\n    for (let i = 0; i < size; i++) {\n      chars[i] = alphabet[(Math.random() * alphabetLength) | 0];\n    }\n    return chars.join('');\n  };\n\n  if (prefix == null) {\n    return generator;\n  }\n\n  // check that the prefix is not part of the alphabet (otherwise prefix checking can fail randomly)\n  if (alphabet.includes(separator)) {\n    throw new InvalidArgumentError({\n      argument: 'separator',\n      message: `The separator \"${separator}\" must not be part of the alphabet \"${alphabet}\".`,\n    });\n  }\n\n  return () => `${prefix}${separator}${generator()}`;\n};\n\n/**\n * A function that generates an ID.\n */\nexport type IdGenerator = () => string;\n\n/**\n * Generates a 16-character random string to use for IDs.\n * Not cryptographically secure.\n */\nexport const generateId = createIdGenerator();","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/provider-utils/src/generate-id.ts#L21-L57","documentation":"createIdGenerator builds IDs as prefix + separator + random-part, and callers often check generated IDs with prefix matching (startsWith). If the separator is a character that also occurs in the random alphabet, prefix detection becomes ambiguous, so the library rejects such configurations at construction time with InvalidArgumentError. It is thrown eagerly when creating the generator (with a prefix), not when generating IDs.","triggerScenarios":"Calling createIdGenerator({ prefix: '...', separator: 'x' }) where separator is one of the characters contained in alphabet — e.g. the default alphabet contains all letters and digits, so any alphanumeric separator like 'a', '0', or 'Z' triggers it; only symbols outside the alphabet (like the default '-') are valid.","commonSituations":"Choosing a letter or digit separator assuming the alphabet is numeric-only; using an empty string separator ('' is contained in every string, so it always throws); copying a custom alphabet but keeping a separator drawn from it; wiring the generator in middleware at startup so the app crashes on boot.","solutions":["Pick a separator character that is not in the alphabet, e.g. the default '-' (or another symbol like '_' or ':' for custom alphabets that exclude it).","If you need a specific separator, exclude that character from your custom alphabet.","Do not pass an empty string as separator; omit the option to use the default '-' or choose a non-empty symbol.","Validate the configuration in tests/bootstrap so the InvalidArgumentError surfaces at deploy time, not at request time."],"exampleFix":"// before: separator 'x' is inside the default alphabet\nconst gen = createIdGenerator({ prefix: 'msg', separator: 'x' });\n\n// after: use a symbol outside the alphabet\nconst gen = createIdGenerator({ prefix: 'msg', separator: '-' });\n// or with a numeric-only alphabet, a letter separator is fine\nconst gen2 = createIdGenerator({ alphabet: '0123456789', prefix: 'msg', separator: 'x' });","handlingStrategy":"validation","validationCode":"function assertValidSeparator(alphabet: string, separator: string): void {\n  if (alphabet.includes(separator)) {\n    throw new Error(`separator \"${separator}\" must not appear in alphabet \"${alphabet}\"`);\n  }\n}\nassertValidSeparator('0123456789ABC...', '-');","typeGuard":null,"tryCatchPattern":"try {\n  const gen = createIdGenerator({ prefix: 'msg', separator });\n} catch (error) {\n  if (error instanceof InvalidArgumentError && error.argument === 'separator') {\n    // fall back to the default '-' separator\n  }\n  throw error;\n}","preventionTips":["Keep the default '-' separator unless your alphabet excludes it.","Never pass '' as separator — it is contained in every alphabet.","When using a custom alphabet, verify the separator character is outside it at bootstrap.","Exercise generator construction in unit tests so config errors surface in CI, not production."],"tags":["configuration","invalid-argument","ids"],"backgroundTag":"invalid-argument-error","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}