{"record":{"id":"6d94698311a1c9b3","repo":"mvanhorn/last30days-skill","slug":"competitors-competitors-must-be-competitor","errorCode":null,"errorMessage":"[Competitors] --competitors must be >= {COMPETITORS_MIN} (got {count}).\\n","messagePattern":"\\[Competitors\\] --competitors must be >= (.+?) \\(got (.+?)\\)\\.\\\\n","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"skills/last30days/scripts/last30days.py","lineNumber":1036,"sourceCode":"            sys.stderr.write(\n                f\"[Competitors] --competitors={competitors_flag} ignored; using \"\n                f\"{count} entries from --competitors-list.\\n\"\n            )\n        if count > COMPETITORS_MAX:\n            sys.stderr.write(\n                f\"[Competitors] --competitors-list has {count} entries, clamping to {COMPETITORS_MAX}.\\n\"\n            )\n            explicit_list = explicit_list[:COMPETITORS_MAX]\n            count = COMPETITORS_MAX\n        return True, count, explicit_list\n\n    if flag_present:\n        count = competitors_flag\n        if count < COMPETITORS_MIN:\n            sys.stderr.write(\n                f\"[Competitors] --competitors must be >= {COMPETITORS_MIN} (got {count}).\\n\"\n            )\n            raise SystemExit(2)\n        if count > COMPETITORS_MAX:\n            sys.stderr.write(\n                f\"[Competitors] --competitors={count} exceeds max {COMPETITORS_MAX}; clamping.\\n\"\n            )\n            count = COMPETITORS_MAX\n        return True, count, []\n\n    # plan_present alone: enable; peers filled by apply_vs_competitor_routing.\n    return True, 0, []\n\n\ndef _missing_sources_for_promo(diag: dict[str, object]) -> str | None:\n    available = set(diag.get(\"available_sources\") or [])\n    missing = []\n    if \"reddit\" not in available:\n        missing.append(\"reddit\")\n    if \"x\" not in available:\n        missing.append(\"x\")","sourceCodeStart":1018,"sourceCodeEnd":1054,"githubUrl":"https://github.com/mvanhorn/last30days-skill/blob/c7460f6114449ddfe6ea3fc2f23c3d910c0e740c/skills/last30days/scripts/last30days.py#L1018-L1054","documentation":"When --competitors N is given without a list, the resolver enforces COMPETITORS_MIN <= N: values below the minimum abort with SystemExit(2), while values above COMPETITORS_MAX are only clamped with a warning (asymmetric on purpose — too few comparisons is statistically useless, too many is just capped).","triggerScenarios":"--competitors 0 or --competitors 1 (if COMPETITORS_MIN is 2+); passing a negative number; a computed count (len of discovered peers) collapsing to 0/1 after filtering.","commonSituations":"Scripts deriving the count from a variable that can be 0 or 1; misunderstanding that 0 does not mean 'auto'.","solutions":["Pass a count within [COMPETITORS_MIN, COMPETITORS_MAX] (check the constants near the resolver; use at least 2).","For automatic peer discovery without an explicit count, use --competitors-plan or the plan-present path instead.","Clamp computed counts in the caller: max(count, 2) or skip the run when discovery found fewer peers than the minimum."],"exampleFix":"# before\n--competitors 1\n\n# after\n--competitors 3","handlingStrategy":"validation","validationCode":"count = max(int(count_arg), 0)\nif count < COMPETITORS_MIN:\n    raise ValueError(f'--competitors must be >= {COMPETITORS_MIN}')\ncount = min(count, COMPETITORS_MAX)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp computed counts: count = min(max(count, COMPETITORS_MIN), COMPETITORS_MAX).","Skip the run rather than passing 0/1 when discovery found too few peers."],"tags":["cli","competitors","validation","arguments"],"backgroundTag":null,"analyzedSha":"c7460f6114449ddfe6ea3fc2f23c3d910c0e740c","analyzedAt":"2026-08-15T03:34:49.540Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}