{"record":{"id":"3da32cbd70b7711a","repo":"AlexsJones/llmfit","slug":"binary-version-mismatch-binary-at-bin-path-repo","errorCode":null,"errorMessage":"Binary version mismatch: binary at {bin_path} reports {binary_version!r} but Cargo.toml (or LLMFIT_VERSION) says {expected_version!r}. Run 'make build' to recompile.","messagePattern":"Binary version mismatch: binary at (.+?) reports (.+?) but Cargo\\.toml \\(or LLMFIT_VERSION\\) says (.+?)\\. Run 'make build' to recompile\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"llmfit-python/hatch_build.py","lineNumber":158,"sourceCode":"    def _check_binary_version(bin_path: Path, expected_version: str) -> None:\n        \"\"\"Run the binary with ``--version`` and verify it matches the expected version.\n\n        Raises ``RuntimeError`` on a mismatch — this indicates a stale build.\n        \"\"\"\n        result = subprocess.run(\n            [str(bin_path), \"--version\"],\n            capture_output=True,\n            check=True,\n            text=True,\n            timeout=5,\n        )\n        output = result.stdout.strip()  # e.g. \"llmfit 0.9.8\"\n        match = re.match(r\"^llmfit v?(\\d+\\.\\d+\\.\\d+)$\", output)\n        if not match:\n            raise RuntimeError(f\"Unexpected output from '{bin_path} --version': {output!r}\")\n        binary_version = match.group(1)\n        if binary_version != expected_version:\n            raise RuntimeError(\n                f\"Binary version mismatch: binary at {bin_path} reports {binary_version!r} \"\n                f\"but Cargo.toml (or LLMFIT_VERSION) says {expected_version!r}. \"\n                \"Run 'make build' to recompile.\",\n            )\n        print(f\"  Binary version OK ({binary_version})\")\n\n    def initialize(self, version: str, build_data: dict) -> None:\n        \"\"\"Locate the platform binary and configure the wheel before it is built.\"\"\"\n        py_target_from_env = os.environ.get(\"LLMFIT_PYTHON_PLATFORM_TAG\")\n        if version == \"editable\" and py_target_from_env:\n            raise ValueError(\n                \"LLMFIT_PYTHON_PLATFORM_TAG is not supported for editable installs. \"\n                \"Let the build system detect the host platform instead.\",\n            )\n        running_platform = self._detect_platform()\n        py_target = py_target_from_env or running_platform\n        if py_target not in TARGET_CONFIGS:\n            raise ValueError(","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/AlexsJones/llmfit/blob/acc7e40c3a0afbd36510a92f2f8f3d5177cfc0fe/llmfit-python/hatch_build.py#L140-L176","documentation":"Raised by _check_binary_version() when the binary executes and reports a version that differs from the package version resolved from Cargo.toml (or the LLMFIT_VERSION override). This is a staleness guard: it prevents packaging a binary compiled before a version bump, or pairing an overridden package version with an unmodified binary.","triggerScenarios":"Bumping [workspace.package].version in Cargo.toml and running `uv build` without recompiling; exporting LLMFIT_VERSION=0.9.8 for a release while the local binary still reports 0.9.7; a CI cache that restores an old target/ directory after the version bump commit.","commonSituations":"Release flows that set the version via env var in one job and reuse a Rust build artifact from another job; developers who bump versions in Cargo.toml during development and forget `make build`.","solutions":["Recompile: `make build` (or `cargo build --release --target <triple>` for standard wheels), then rebuild the wheel","If LLMFIT_VERSION is set, verify it matches what the binary reports: `./target/release/llmfit --version` vs `echo $LLMFIT_VERSION` — unset the override if it is stale","In CI, always run the cargo build step after any step that touches Cargo.toml or exports LLMFIT_VERSION, and avoid caching target/ across version bumps"],"exampleFix":"# before\n# Cargo.toml bumped to 0.9.9, binary still from 0.9.8\nuv build  # RuntimeError: Binary version mismatch\n\n# after\ncargo build --release --target x86_64-unknown-linux-gnu\nuv build","handlingStrategy":"validation","validationCode":"import os, re, subprocess, tomllib\nexpected = os.environ.get(\"LLMFIT_VERSION\") or tomllib.load(open(\"Cargo.toml\", \"rb\"))[\"workspace\"][\"package\"][\"version\"]\nout = subprocess.run([\"./target/release/llmfit\", \"--version\"], capture_output=True, text=True, timeout=5).stdout.strip()\nactual = re.fullmatch(r\"llmfit v?(\\d+\\.\\d+\\.\\d+)\", out).group(1)\nif actual != expected:\n    raise SystemExit(f\"stale binary {actual} vs expected {expected} — recompile before building the wheel\")","typeGuard":null,"tryCatchPattern":"try:\n    hook._check_binary_version(bin_path, pypi_version)\nexcept RuntimeError as e:\n    raise SystemExit(f\"stale artifact: {e}\")","preventionTips":["Always recompile after bumping the Cargo.toml version or setting LLMFIT_VERSION","In CI, run the cargo build step in the same job (after) the version is finalized","Do not cache target/ across version-bump commits"],"tags":["python","rust","version-mismatch","packaging","stale-build"],"backgroundTag":"version-mismatch","analyzedSha":"acc7e40c3a0afbd36510a92f2f8f3d5177cfc0fe","analyzedAt":"2026-08-17T10:35:29.658Z","contentChangedAt":"2026-08-17T10:35:29.658Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}