{"record":{"id":"c07123f507cc00f6","repo":"Hmbown/CodeWhale","slug":"pending-groups-may-contain-string-literals-only","errorCode":null,"errorMessage":"PENDING_GROUPS may contain string literals only","messagePattern":"PENDING_GROUPS may contain string literals only","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scripts/check-command-migration-manifest.py","lineNumber":477,"sourceCode":"def load_topology(path: Path = TOPOLOGY_PATH) -> dict:\n    with path.open(encoding=\"utf-8\") as fh:\n        return json.load(fh)\n\n\ndef load_pending_groups(path: Path = CONTRACT_PATH) -> list[str]:\n    \"\"\"Read the TUI frontier projection from `PENDING_GROUPS` fail-closed.\"\"\"\n    source = path.read_text(encoding=\"utf-8\")\n    match = re.search(\n        r\"pub\\(crate\\)\\s+const\\s+PENDING_GROUPS\\s*:\\s*&\\[&str\\]\\s*=\\s*&\\[(.*?)\\];\",\n        source,\n        re.DOTALL,\n    )\n    if match is None:\n        raise ValueError(f\"could not locate PENDING_GROUPS in {path}\")\n    body = match.group(1)\n    stripped = re.sub(r'\"(?:\\\\.|[^\"\\\\])*\"', \"\", body)\n    if re.fullmatch(r\"[\\s,]*\", stripped) is None:\n        raise ValueError(\"PENDING_GROUPS may contain string literals only\")\n    return re.findall(r'\"((?:\\\\.|[^\"\\\\])*)\"', body)\n\n\ndef validate_pending_projection(doc: dict, pending: list[str]) -> list[ManifestViolation]:\n    if pending != doc.get(\"frontier\"):\n        return [ManifestViolation(\n            \"frontier-projection\",\n            \"PENDING_GROUPS\",\n            f\"TUI projection {pending!r} does not equal JSON frontier {doc.get('frontier')!r}\",\n        )]\n    return []\n\n\ndef load_topology_at_ref(ref: str, root: Path = REPO_ROOT) -> dict | None:\n    \"\"\"Load the topology from a Git revision; return None before its introduction.\"\"\"\n    commit = subprocess.run(\n        [\"git\", \"rev-parse\", \"--verify\", f\"{ref}^{{commit}}\"],\n        cwd=root,","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-command-migration-manifest.py#L459-L495","documentation":"After stripping all string literals from the PENDING_GROUPS array body, load_pending_groups requires only whitespace and commas to remain. If any other token survives, the array contains non-literal elements (expressions, constants, comments interfering, or malformed syntax) that the manifest checker cannot safely treat as a plain list of command names, so it raises ValueError.","triggerScenarios":"Running the checker when PENDING_GROUPS contains items like other constants (e.g. include! or concatenation), doc comments inside the array that aren't stripped, escaped/odd tokens, or trailing code accidentally left inside the brackets.","commonSituations":"A developer added a helper const or format expression into the array instead of a plain string literal; a macro invocation was used to build the list; an editing mistake left stray code inside the array body.","solutions":["Inspect PENDING_GROUPS and replace any non-literal entries with plain string literals","Remove stray code or unstripped comments from inside the array brackets","Generate the literal list (e.g. via a small macro expansion or manually) instead of building it at compile time","If the format must change, update load_pending_groups' validation accordingly"],"exampleFix":"// before\npub(crate) const PENDING_GROUPS: &[&str] = &[GROUP_A, \"cmd_b\"];\n// after\npub(crate) const PENDING_GROUPS: &[&str] = &[\"cmd_a\", \"cmd_b\"];","handlingStrategy":"validation","validationCode":"body = re.search(r'=\\s*&\\[(.*?)\\];', src, re.DOTALL).group(1)\nstripped = re.sub(r'\"(?:\\\\.|[^\"\\\\])*\"', \"\", body)\nassert re.fullmatch(r\"[\\s,]*\", stripped), \"non-literal inside PENDING_GROUPS\"","typeGuard":null,"tryCatchPattern":"try:\n    pending = load_pending_groups(path)\nexcept ValueError as exc:\n    print(f\"PENDING_GROUPS must be plain literals: {exc}\")\n    sys.exit(1)","preventionTips":["Only place plain \"...\" string literals inside PENDING_GROUPS","Avoid referencing other consts or macros in the array; inline the values","Review any rustfmt/attr changes around the array in code review","Run the checker locally before pushing Rust changes touching the manifest"],"tags":["regex-parsing","validation","build-script"],"backgroundTag":"invalid-argument-format","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}