nexu-io/open-design · error

[Competitors] --competitors must be >= {COMPETITORS_MIN} (go

Error message

[Competitors] --competitors must be >= {COMPETITORS_MIN} (got {count}).\n

What it means

In the flag-only branch of resolve_competitors() (around line 463), when `--competitors N` is supplied without an explicit list and N is below COMPETITORS_MIN, the code writes `[Competitors] --competitors must be >= <MIN> (got <N>).` and raises SystemExit(2). Values above COMPETITORS_MAX are clamped (warned, not fatal); only the lower bound is a hard failure. This prevents asking for fewer than the meaningful minimum.

Source

Thrown at design-templates/last30days/scripts/last30days.py:463

            sys.stderr.write(
                f"[Competitors] --competitors={competitors_flag} ignored; using "
                f"{count} entries from --competitors-list.\n"
            )
        if count > COMPETITORS_MAX:
            sys.stderr.write(
                f"[Competitors] --competitors-list has {count} entries, clamping to {COMPETITORS_MAX}.\n"
            )
            explicit_list = explicit_list[:COMPETITORS_MAX]
            count = COMPETITORS_MAX
        return True, count, explicit_list

    # flag_present, no explicit list
    count = competitors_flag
    if count < COMPETITORS_MIN:
        sys.stderr.write(
            f"[Competitors] --competitors must be >= {COMPETITORS_MIN} (got {count}).\n"
        )
        raise SystemExit(2)
    if count > COMPETITORS_MAX:
        sys.stderr.write(
            f"[Competitors] --competitors={count} exceeds max {COMPETITORS_MAX}; clamping.\n"
        )
        count = COMPETITORS_MAX
    return True, count, []


def _missing_sources_for_promo(diag: dict[str, object]) -> str | None:
    available = set(diag.get("available_sources") or [])
    missing = []
    if "reddit" not in available:
        missing.append("reddit")
    if "x" not in available:
        missing.append("x")
    if "grounding" not in available:
        missing.append("web")
    if not missing:

View on GitHub (pinned to 5be4028344)

Solutions

  1. Pass a value >= COMPETITORS_MIN (check the constant in the file if unsure).
  2. If you want zero competitors, omit both `--competitors` and `--competitors-list` (the function returns False,0,[]).
  3. If you want exactly one named competitor, use `--competitors-list name`.

Example fix

# before
python3.12 last30days.py --topic x --competitors 0
# after (omit to disable)
python3.12 last30days.py --topic x
# after (meet minimum)
python3.12 last30days.py --topic x --competitors 3
Defensive patterns

Strategy: validation

Validate before calling

if args.competitors is not None and args.competitors < COMPETITORS_MIN:
    raise ValueError(f'--competitors must be >= {COMPETITORS_MIN}, got {args.competitors}')

Prevention

When it happens

Trigger: `--competitors 0`, `--competitors -1`, or any value below COMPETITORS_MIN (commonly 2 or 3) when no `--competitors-list` is given.

Common situations: Passing 0 to disable competitors (use `--competitors-list` empty / omit instead); negative value from an arithmetic bug in a wrapper script; misreading the min.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/507755fc89f8fa3c. Report an issue: GitHub.