pbakaus/impeccable · error · 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 `candidateCount` is not an integer in the closed range [5,7] (default 7). The count controls how many candidates the deterministic dice rank; the range is narrow by design so rolls stay comparable. Non-integers and values outside 5-7 are both rejected.
Source
Thrown at skill/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
- Pass exactly 5, 6, or 7.
- Coerce and clamp at the CLI boundary: Math.min(7, Math.max(5, Math.round(n))).
- If you genuinely need more candidates, that is a design change to the function, not a runtime tweak.
Example fix
// before
await seedConcepts({ scope: 'surface', candidateCount: 10 });
// before (string from CLI)
await seedConcepts({ scope: 'surface', candidateCount: argv['--candidate-count'] });
// after
await seedConcepts({ scope: 'surface', candidateCount: 7 }); // 5|6|7 only Defensive patterns
Strategy: validation
Validate before calling
// Coerce and clamp candidateCount at the boundary.
function parseCandidateCount(raw) {
const n = Math.round(Number(raw ?? 7));
if (!Number.isInteger(n) || n < 5 || n > 7) {
throw new Error('--candidate-count must be an integer from 5 to 7');
}
return n;
} Type guard
function isValidCandidateCount(v) {
return v == null || (Number.isInteger(v) && v >= 5 && v <= 7);
} Prevention
- Pass only 5, 6, or 7 (default 7).
- Coerce argv with Number() and Math.round, then range-check.
- Needing >7 is a design change, not a runtime option.
When it happens
Trigger: Passing 3, 4, 8, or 10; passing a float like 6.5; passing candidateCount as a string from argv; computing the count dynamically and overshooting the range.
Common situations: A caller assuming any positive integer is fine; CLI forwarding an uncoerced string; a UI slider with a wider range than the function accepts.
Related errors
- concept-seed: --reroll must be a non-negative integer
- concept-seed: --scope must be direction or surface
- concept-seed: --register must be safer or bolder
- concept-seed: --register steers a re-roll round; pass --rero
- concept-seed: --register applies to direction rounds only
AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13).
Data as JSON: /api/errors/2b8d969a1c76e5a3.
Report an issue: GitHub.