{"record":{"id":"ac0b8cb9d9efb969","repo":"Stirling-Tools/Stirling-PDF","slug":"path-invalid-toml-exc","errorCode":null,"errorMessage":"{path}: invalid TOML: {exc}","messagePattern":"(.+?): invalid TOML: (.+?)","errorType":"exception","errorClass":"SortError","httpStatus":null,"severity":"error","filePath":"scripts/pre-commit/sort_locale_toml.py","lineNumber":48,"sourceCode":"\n\ndef tracked_files(path_specs: list[str]) -> list[str]:\n    result = subprocess.run(\n        [\"git\", \"ls-files\", \"-z\", *path_specs],\n        check=True,\n        capture_output=True,\n        text=True,\n    )\n    return [path for path in result.stdout.split(\"\\0\") if path]\n\n\ndef sort_file(path: str, fix: bool) -> bool:\n    \"\"\"Rewrite one file if `fix`; return whether it was not already sorted.\"\"\"\n    text = Path(path).read_text(encoding=\"utf-8\")\n    try:\n        original = tomllib.loads(text)\n    except tomllib.TOMLDecodeError as exc:\n        raise SortError(f\"{path}: invalid TOML: {exc}\") from exc\n\n    expected = tomli_w.dumps(ordered(original))\n    if expected == text:\n        return False\n\n    try:\n        reordered = tomllib.loads(expected)\n    except tomllib.TOMLDecodeError as exc:\n        raise SortError(f\"{path}: refusing to sort, the sorted output is not valid TOML: {exc}\") from exc\n    if reordered != original:\n        raise SortError(f\"{path}: refusing to sort, sorting would change the file's contents\")\n\n    if fix:\n        Path(path).write_text(expected, encoding=\"utf-8\")\n    return True\n\n\ndef main() -> int:","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/scripts/pre-commit/sort_locale_toml.py#L30-L66","documentation":"sort_locale_toml.py is the pre-commit hook that key-sorts locale translation.toml files. It parses each tracked file with the stdlib tomllib (sort_locale_toml.py:46) and raises SortError on the first file tomllib cannot parse, forwarding the parser's own message. This is a hard precondition: the hook will not rewrite a file it cannot parse, because it cannot guarantee semantic preservation. It therefore indicates a genuine syntax defect in the committed locale file, not a sorting problem.","triggerScenarios":"A translator committed a .toml with an unterminated string, a duplicate key, an invalid escape sequence, or an unquoted value containing special characters; a merge introduced hand-edited TOML that was never re-validated; a file that parses in a lenient tool but not in strict tomllib.","commonSituations":"Editing locale TOML by hand without a TOML-aware editor; a copy-paste that dropped a closing quote; CI running the pre-commit hook against a file edited in a generic text editor.","solutions":["Open the file at the line/column reported in {exc} and fix the TOML syntax (unterminated strings, duplicate keys, bad escapes, unquoted special values)","Reproduce locally to get the exact location: `python -c \"import tomllib; tomllib.loads(open('<file>').read())\"`","Re-run `python scripts/pre-commit/sort_locale_toml.py <file>` to confirm it parses, then optionally add `--fix` to sort it"],"exampleFix":"# before -- locale/en/translation.toml (broken)\ngreeting = \"Hello\nfarewell = \"Bye\"\n\n# after\ngreeting = \"Hello\"\nfarewell = \"Bye\"","handlingStrategy":"try-catch","validationCode":"import tomllib\nfrom pathlib import Path\n\ndef is_valid_toml(path: str) -> bool:\n    try:\n        tomllib.loads(Path(path).read_text(encoding=\"utf-8\"))\n        return True\n    except tomllib.TOMLDecodeError:\n        return False","typeGuard":null,"tryCatchPattern":"for path in tracked_files(pathspecs):\n    try:\n        sort_file(path, fix)\n    except SortError as exc:\n        errors.append(str(exc))  # collect and continue, do not abort the whole run","preventionTips":["Use a TOML-aware editor/linter for locale files so syntax errors surface before commit","Add a standalone tomllib parse gate in the locale-editing CI separate from the sort hook","Never hand-resolve a TOML merge conflict without re-parsing the result"],"tags":["toml","pre-commit","locale","config","parsing"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}