Stirling-Tools/Stirling-PDF · error · SortError

{path}: invalid TOML: {exc}

Error message

{path}: invalid TOML: {exc}

What it means

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.

Source

Thrown at scripts/pre-commit/sort_locale_toml.py:48


def tracked_files(path_specs: list[str]) -> list[str]:
    result = subprocess.run(
        ["git", "ls-files", "-z", *path_specs],
        check=True,
        capture_output=True,
        text=True,
    )
    return [path for path in result.stdout.split("\0") if path]


def sort_file(path: str, fix: bool) -> bool:
    """Rewrite one file if `fix`; return whether it was not already sorted."""
    text = Path(path).read_text(encoding="utf-8")
    try:
        original = tomllib.loads(text)
    except tomllib.TOMLDecodeError as exc:
        raise SortError(f"{path}: invalid TOML: {exc}") from exc

    expected = tomli_w.dumps(ordered(original))
    if expected == text:
        return False

    try:
        reordered = tomllib.loads(expected)
    except tomllib.TOMLDecodeError as exc:
        raise SortError(f"{path}: refusing to sort, the sorted output is not valid TOML: {exc}") from exc
    if reordered != original:
        raise SortError(f"{path}: refusing to sort, sorting would change the file's contents")

    if fix:
        Path(path).write_text(expected, encoding="utf-8")
    return True


def main() -> int:

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Open the file at the line/column reported in {exc} and fix the TOML syntax (unterminated strings, duplicate keys, bad escapes, unquoted special values)
  2. Reproduce locally to get the exact location: `python -c "import tomllib; tomllib.loads(open('<file>').read())"`
  3. Re-run `python scripts/pre-commit/sort_locale_toml.py <file>` to confirm it parses, then optionally add `--fix` to sort it

Example fix

# before -- locale/en/translation.toml (broken)
greeting = "Hello
farewell = "Bye"

# after
greeting = "Hello"
farewell = "Bye"
Defensive patterns

Strategy: try-catch

Validate before calling

import tomllib
from pathlib import Path

def is_valid_toml(path: str) -> bool:
    try:
        tomllib.loads(Path(path).read_text(encoding="utf-8"))
        return True
    except tomllib.TOMLDecodeError:
        return False

Try / catch

for path in tracked_files(pathspecs):
    try:
        sort_file(path, fix)
    except SortError as exc:
        errors.append(str(exc))  # collect and continue, do not abort the whole run

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/ac0b8cb9d9efb969. Report an issue: GitHub.