{"record":{"id":"0e4b1dcf5041ddd8","repo":"Hmbown/CodeWhale","slug":"could-not-locate-pending-groups-in-path","errorCode":null,"errorMessage":"could not locate PENDING_GROUPS in {path}","messagePattern":"could not locate PENDING_GROUPS in (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scripts/check-command-migration-manifest.py","lineNumber":473,"sourceCode":"    violations.extend(validate_frontier(topology, doc.get(\"frontier\", [])))\n    return violations\n\n\ndef 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:","sourceCodeStart":455,"sourceCodeEnd":491,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-command-migration-manifest.py#L455-L491","documentation":"load_pending_groups in scripts/check-command-migration-manifest.py extracts the PENDING_GROUPS constant (a pub(crate) &[&str] array) from a Rust source file using a regex. It raises ValueError when the regex finds no match, meaning the PENDING_GROUPS declaration is absent, was renamed, or its syntax no longer matches the expected pattern.","triggerScenarios":"Running the migration-manifest checker against a Rust file at {path} that no longer contains a declaration matching pub(crate) const PENDING_GROUPS: &[&str] = &[...]; — e.g. the constant was removed after the migration completed, renamed, made public (pub instead of pub(crate)), or reformatted with comments/attributes between the tokens.","commonSituations":"The migration frontier was emptied and the constant deleted; a refactor changed the type (e.g. to a Vec or added a type alias); rustfmt introduced line breaks the DOTALL regex still expects to bridge but attribute lines broke the signature; checker run against the wrong file path.","solutions":["Confirm the path points at the Rust file that currently owns PENDING_GROUPS","Restore or re-add the PENDING_GROUPS declaration in the expected pub(crate) const form","If the declaration was intentionally removed (migration done), update or retire the checker step rather than the source","Adjust the regex if the constant's syntax legitimately changed (e.g. visibility or type)"],"exampleFix":"// before (checker fails: no constant found)\n// (constant deleted)\n// after\npub(crate) const PENDING_GROUPS: &[&str] = &[\n    \"some_pending_command\",\n];","handlingStrategy":"validation","validationCode":"import re, pathlib\nsrc = pathlib.Path(path).read_text()\nassert re.search(r\"pub\\(crate\\)\\s+const\\s+PENDING_GROUPS\\s*:\\s*&\\[&str\\]\", src), \"PENDING_GROUPS declaration missing\"","typeGuard":null,"tryCatchPattern":"try:\n    pending = load_pending_groups(path)\nexcept ValueError as exc:\n    print(f\"manifest checker cannot proceed: {exc}\")\n    sys.exit(1)","preventionTips":["Never delete PENDING_GROUPS until the checker itself is retired","Keep the declaration on its canonical pub(crate) const form; avoid reformatting that changes visibility or type","Add a unit test that runs load_pending_groups against the real file","Grep for PENDING_GROUPS before renaming or moving the owning file"],"tags":["regex-parsing","rust","build-script"],"backgroundTag":"record-not-found","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"}