Skip to content

fix(design/variants): guard --count against NaN/zero/negative input#2033

Open
jbetala7 wants to merge 1 commit into
garrytan:mainfrom
jbetala7:oss/fix-2032-variants-count-guard
Open

fix(design/variants): guard --count against NaN/zero/negative input#2033
jbetala7 wants to merge 1 commit into
garrytan:mainfrom
jbetala7:oss/fix-2032-variants-count-guard

Conversation

@jbetala7

Copy link
Copy Markdown
Contributor

Problem

design variants --count <bad value> silently produces zero variants and emits a misleading JSON result.

--count is parsed with parseInt and never validated (design/src/cli.ts:200), and variants() only clamped the upper bound (design/src/variants.ts):

const count = Math.min(options.count, 7); // Cap at 7 style variations

So bad inputs flow through. Measured against the real clamp + JSON-emit path on main (c7ae632):

--count generated JSON count
abc 0 null
0 0 0
-2 0 -2
3 3 3
10 7 7

Math.min(NaN, 7) is NaN, so for (i = 0; i < NaN; i++) never runs and the command exits "successfully" having created nothing, reporting "count": null. A single typo (--count e) is enough.

Root cause

No lower-bound or NaN guard on the requested count — only the <= 7 cap.

Fix

Add a small exported, pure normalizeVariantCount helper and use it in place of the bare cap:

export function normalizeVariantCount(count: number): number {
  if (!Number.isFinite(count)) return 3;            // unparseable -> default
  return Math.max(1, Math.min(Math.trunc(count), 7)); // clamp to [1, 7]
}
  • non-finite (NaN/Infinity) -> default 3
  • 0 / negative -> 1
  • > 7 -> 7 (unchanged)
  • in-range -> unchanged

This mirrors the exported-helper validation shape proposed for --api-timeout in #1528, but is independent of it (different flag).

Testing

bun test design/test/variants-retry-after.test.ts -> 10 pass / 0 fail (5 existing + 5 new). Full bun test design/test/ passes. The helper is pure, so the regression is pinned without an ANTHROPIC_API_KEY/OPENAI_API_KEY.

Scope / collision check

Fixes #2032

`design variants --count <bad value>` silently produced zero variants
because the generation loop only clamped the upper bound. `--count` arrives
via `parseInt`, which yields NaN for non-numeric input ("abc") and passes
zero/negative values straight through. `Math.min(NaN, 7)` is NaN, so the
`for (i = 0; i < NaN; i++)` loop never ran and the JSON result emitted
`"count": null` — a confusing success-with-nothing for any caller parsing it.

Add an exported `normalizeVariantCount` helper that clamps to the supported
[1, 7] range and falls back to the default of 3 for non-finite input, then
use it where the bare upper-bound cap was. Pure and unit-tested so the
behavior is pinned without an API key.

Fixes garrytan#2032

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@trunk-io

trunk-io Bot commented Jun 17, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@time-attack

Copy link
Copy Markdown
Contributor

@16francej ensures numers are real. merge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

design variants: --count silently generates zero variants on NaN/0/negative input

2 participants