{"record":{"id":"4fc900fda48cab57","repo":"mvanhorn/last30days-skill","slug":"competitors-competitors-list-is-empty-n","errorCode":null,"errorMessage":"[Competitors] --competitors-list is empty.\\n","messagePattern":"\\[Competitors\\] --competitors-list is empty\\.\\\\n","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"skills/last30days/scripts/last30days.py","lineNumber":1005,"sourceCode":"\n    - (False, 0, []) when neither flag, list, nor plan is set.\n    - An explicit ``--competitors-list`` always wins; count is derived from list length.\n    - ``--competitors-plan`` alone enables mode with an empty peer list; vs-routing\n      fills peers from the vs-string or plan keys.\n    - A numeric count outside [1, 6] is clamped with a stderr warning.\n    - count <= 0 (explicit) raises SystemExit(2).\n    \"\"\"\n    explicit_list: list[str] = []\n    list_flag_provided = args.competitors_list is not None\n    if list_flag_provided:\n        explicit_list = [\n            entity.strip()\n            for entity in args.competitors_list.split(\",\")\n            if entity.strip()\n        ]\n        if not explicit_list:\n            sys.stderr.write(\"[Competitors] --competitors-list is empty.\\n\")\n            raise SystemExit(2)\n\n    competitors_flag = args.competitors\n    list_present = bool(explicit_list)\n    flag_present = competitors_flag is not None\n    plan_present = bool(getattr(args, \"competitors_plan\", None))\n\n    if not list_present and not flag_present and not plan_present:\n        return False, 0, []\n\n    if list_present:\n        count = len(explicit_list)\n        if flag_present and competitors_flag != count:\n            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(","sourceCodeStart":987,"sourceCodeEnd":1023,"githubUrl":"https://github.com/mvanhorn/last30days-skill/blob/c7460f6114449ddfe6ea3fc2f23c3d910c0e740c/skills/last30days/scripts/last30days.py#L987-L1023","documentation":"In the competitors-flag resolver: when --competitors-list is provided (non-None) but splitting on commas yields zero non-blank entries, the run aborts with SystemExit(2). This distinguishes 'flag absent' (None) from 'flag given but empty' — the latter is treated as a user error, not a no-op.","triggerScenarios":"--competitors-list '' , --competitors-list ',' , or a value made only of spaces/commas. Any non-empty trimmed entry would proceed, so only fully-blank values trigger this.","commonSituations":"Templated commands injecting an empty variable: --competitors-list \"$ENTITIES\" with ENTITIES unset or empty; agent building the flag from an empty discovery result.","solutions":["Populate the list: --competitors-list 'Acme,Beta'.","Omit the flag entirely when no explicit competitors are known (auto-discovery via --competitors N can fill them).","Guard callers: only append the flag when the joined string is non-empty."],"exampleFix":"# before\ncmd += ['--competitors-list', ','.join(entities)]  # entities == []\n\n# after\nif entities:\n    cmd += ['--competitors-list', ','.join(entities)]\nelse:\n    cmd += ['--competitors', '3']","handlingStrategy":"validation","validationCode":"entities = [e.strip() for e in raw.split(',') if e.strip()]\nif raw is not None and not entities:\n    raise ValueError('--competitors-list given but contains no non-empty entries')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Omit --competitors-list when discovery yields no names; use --competitors N for auto-fill.","Never inject empty shell variables into the flag."],"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"}