{"record":{"id":"adca461ddc6abe05","repo":"pbakaus/impeccable","slug":"concept-seed-reroll-must-be-a-non-negative-inte-adca46","errorCode":null,"errorMessage":"concept-seed: --reroll must be a non-negative integer","messagePattern":"concept-seed: --reroll must be a non-negative integer","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skill/scripts/concept-seed.mjs","lineNumber":310,"sourceCode":"const SEED_MODES = new Set(['persuade', 'operate', 'read', 'experience']);\n\nexport function renderConceptSeed({\n  scope = 'surface',\n  key = process.env.IMPECCABLE_CONCEPT_SEED || crypto.randomBytes(4).toString('hex'),\n  reroll = 0,\n  register = null,\n  mode = null,\n  grain = null,\n  platform = null,\n  candidateCount = 7,\n  catalogDir = CATALOG_DIR,\n  _resolvedData = undefined,\n} = {}) {\n  if (scope !== 'surface' && scope !== 'direction') {\n    throw new Error('concept-seed: --scope must be direction or surface');\n  }\n  if (!Number.isInteger(reroll) || reroll < 0) {\n    throw new Error('concept-seed: --reroll must be a non-negative integer');\n  }\n  if (register !== null && register !== 'safer' && register !== 'bolder') {\n    throw new Error('concept-seed: --register must be safer or bolder');\n  }\n  if (register !== null && reroll < 1) {\n    throw new Error('concept-seed: --register steers a re-roll round; pass --reroll <n> with it');\n  }\n  if (register !== null && scope !== 'direction') {\n    throw new Error('concept-seed: --register applies to direction rounds only');\n  }\n  if (mode !== null && !SEED_MODES.has(mode)) {\n    throw new Error('concept-seed: --mode must be persuade, operate, read, or experience');\n  }\n  // Grain needs no mode: how much of the product is in play is independent of\n  // which register of work it is.\n  if (grain !== null && !COMPOSITION_GRAINS.includes(grain)) {\n    throw new Error(`concept-seed: --grain must be one of ${COMPOSITION_GRAINS.join(', ')}`);\n  }","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/pbakaus/impeccable/blob/d14711ae3d1a1dd62dee61a358d27f107c51ccd0/skill/scripts/concept-seed.mjs#L292-L328","documentation":"Thrown when the `reroll` argument is not a non-negative integer (must pass Number.isInteger AND be >= 0; default 0). Reroll selects which deterministic variant the seeded dice produce, so fractional or negative values are meaningless. A common cause is CLI parsing reroll as a string, which fails Number.isInteger.","triggerScenarios":"Passing reroll as a string like '2' from argv without Number() coercion; passing a negative number; passing 1.5 or NaN; passing undefined which then gets mishandled upstream.","commonSituations":"CLI handler forwarding process.argv values as strings; a caller computing reroll from a formula that can yield a float; passing -1 to mean 'previous'.","solutions":["Coerce and validate reroll to an integer before calling: Number.isInteger(+v) ? +v : ...","Pass 0 for the base round and a positive integer (1, 2, ...) for re-rolls.","Clamp or reject non-integer input at the CLI boundary."],"exampleFix":"// before (CLI forwards a string)\nawait seedConcepts({ reroll: argv['--reroll'] }); // '2' -> throws\n\n// after\nconst raw = Number(argv['--reroll'] ?? 0);\nawait seedConcepts({ reroll: Number.isInteger(raw) && raw >= 0 ? raw : 0 });","handlingStrategy":"validation","validationCode":"// Coerce and validate reroll at the CLI boundary.\nfunction parseReroll(raw) {\n  const n = Number(raw ?? 0);\n  if (!Number.isInteger(n) || n < 0) {\n    throw new Error('--reroll must be a non-negative integer');\n  }\n  return n;\n}","typeGuard":"function isValidReroll(v) {\n  return v == null || (Number.isInteger(v) && v >= 0);\n}","tryCatchPattern":null,"preventionTips":["Coerce argv strings with Number() and check Number.isInteger before passing.","Pass 0 for the base round; use 1, 2, ... for re-rolls.","Never pass -1 or a float; clamp or reject at the boundary."],"tags":["validation","concept-seed","cli","numeric"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}