pbakaus/impeccable · error

concept-seed: --candidate-count must be an integer from 5 to

Error message

concept-seed: --candidate-count must be an integer from 5 to 7

What it means

Thrown when --candidate-count is not an integer in [5,7]. The build index is computed as 3 + floor(unit * (candidateCount - 2)) and the dealt-indices logic assumes a hand of 5–7 grounded candidates, so values outside that range break the index math and the deal shape.

Source

Thrown at plugin/skills/impeccable/scripts/concept-seed.mjs:333

  if (register !== null && reroll < 1) {
    throw new Error('concept-seed: --register steers a re-roll round; pass --reroll <n> with it');
  }
  if (register !== null && scope !== 'direction') {
    throw new Error('concept-seed: --register applies to direction rounds only');
  }
  if (mode !== null && !SEED_MODES.has(mode)) {
    throw new Error('concept-seed: --mode must be persuade, operate, read, or experience');
  }
  // Grain needs no mode: how much of the product is in play is independent of
  // which register of work it is.
  if (grain !== null && !COMPOSITION_GRAINS.includes(grain)) {
    throw new Error(`concept-seed: --grain must be one of ${COMPOSITION_GRAINS.join(', ')}`);
  }
  if (platform !== null && !COMPOSITION_PLATFORMS.includes(platform)) {
    throw new Error(`concept-seed: --platform must be one of ${COMPOSITION_PLATFORMS.join(', ')}`);
  }
  if (!Number.isInteger(candidateCount) || candidateCount < 5 || candidateCount > 7) {
    throw new Error('concept-seed: --candidate-count must be an integer from 5 to 7');
  }
  const unit = (salt) => {
    const h = crypto.createHash('sha256').update(`${scope}:${salt}:${key}`).digest();
    return h.readUInt32BE(0) / 0xffffffff;
  };
  const indexSalt = reroll === 0 ? 'index' : `index:reroll-${reroll}`;
  const buildIndex = 3 + Math.floor(unit(indexSalt) * (candidateCount - 2)); // 3..candidateCount
  // Surface scope deals a hand of three grounded structures: one card is not
  // a choice, and the full ranked list would hand selection back to the
  // model's taste. The dice pick all three; the primary index leads. The
  // no-lineup rule stays direction-only, where it was written for worlds.
  const dealtIndices = [buildIndex];
  for (let draw = 0; scope === 'surface' && dealtIndices.length < Math.min(3, candidateCount); draw += 1) {
    const idx = 1 + Math.floor(unit(`${indexSalt}:deal-${draw}`) * candidateCount);
    if (!dealtIndices.includes(idx)) dealtIndices.push(idx);
    if (draw > 64) { // hash repeats cannot stall the deal
      for (let fill = 1; dealtIndices.length < Math.min(3, candidateCount); fill += 1) {
        if (!dealtIndices.includes(fill)) dealtIndices.push(fill);

View on GitHub (pinned to d14711ae3d)

Solutions

  1. Pass --candidate-count 5, 6, or 7 (default is 7).
  2. Programmatic callers should validate Number.isInteger and the 5–7 range before calling.

Example fix

// before
seedConcepts({ scope: 'direction', candidateCount: 10 });

// after
seedConcepts({ scope: 'direction', candidateCount: 7 });
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isInteger(candidateCount) || candidateCount < 5 || candidateCount > 7) {
  throw new Error('--candidate-count must be an integer from 5 to 7');
}

Type guard

function isValidCandidateCount(value) {
  return Number.isInteger(value) && value >= 5 && value <= 7;
}

Try / catch

try {
  await seedConcepts({ scope: 'direction', candidateCount });
} catch (err) {
  if (/--candidate-count must be/.test(err.message)) {
    console.error('Pass --candidate-count 5, 6, or 7.');
  } else throw err;
}

Prevention

When it happens

Trigger: Passing --candidate-count 4, 8, 10, a non-integer (5.5), or a string. The check is Number.isInteger(candidateCount) && candidateCount >= 5 && candidateCount <= 7.

Common situations: A caller assuming more candidates = better; CLI parsing leaving a string; a wrapper exposing a free spin count.

Related errors


AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13). Data as JSON: /api/errors/37a89e229bf7f40f. Report an issue: GitHub.