{"record":{"id":"9a478925a8320b77","repo":"AlexsJones/llmfit","slug":"binary-not-found-at-bin-path-expected-it-to-be","errorCode":null,"errorMessage":"Binary not found at {bin_path}. Expected it to be built for target {upstream_target!r}.","messagePattern":"Binary not found at (.+?)\\. Expected it to be built for target (.+?)\\.","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"llmfit-python/hatch_build.py","lineNumber":113,"sourceCode":"    def _detect_platform() -> str:\n        \"\"\"Return the best platform tag for the current machine.\"\"\"\n        best = next((t.platform for t in sys_tags() if t.platform in TARGET_CONFIGS), None)\n        if best is not None:\n            return best\n        first = next(t.platform for t in sys_tags())\n        raise RuntimeError(f\"No suitable wheel platform found for runtime platform {first!r}.\")\n\n    @staticmethod\n    def _find_binary_for_target(llmfit_root: Path, py_target: str) -> Path:\n        \"\"\"Find the binary compiled for a specific Rust target.\n\n        Looks in ``target/{upstream_target}/release/``, which is where Cargo\n        places the binary when built with ``--target``.\n        \"\"\"\n        upstream_target, binary_name = TARGET_CONFIGS[py_target]\n        bin_path = llmfit_root / \"target\" / upstream_target / \"release\" / binary_name\n        if not bin_path.is_file():\n            raise FileNotFoundError(\n                f\"Binary not found at {bin_path}. Expected it to be built for target {upstream_target!r}.\",\n            )\n        return bin_path\n\n    @staticmethod\n    def _find_local_binary(llmfit_root: Path) -> Path:\n        \"\"\"Find the locally compiled binary in default Cargo output locations.\n\n        Checks ``target/debug/`` first (from ``make build``), then\n        ``target/release/`` (from ``make release``).\n        \"\"\"\n        binary_name = \"llmfit.exe\" if sys.platform == \"win32\" else \"llmfit\"\n        candidates = [\n            llmfit_root / \"target\" / \"debug\" / binary_name,\n            llmfit_root / \"target\" / \"release\" / binary_name,\n        ]\n        for candidate in candidates:\n            if candidate.is_file():","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/AlexsJones/llmfit/blob/acc7e40c3a0afbd36510a92f2f8f3d5177cfc0fe/llmfit-python/hatch_build.py#L95-L131","documentation":"Raised by LlmfitBinaryBuildHook._find_binary_for_target() when building a standard (release) wheel. Hatchling expects the Rust binary to already exist at target/<upstream_target>/release/llmfit (or llmfit.exe), i.e. the location Cargo produces when built with an explicit --target. The hook never compiles Rust itself, so a missing cross-compiled artifact is a FileNotFoundError.","triggerScenarios":"Running `uv build` / `hatch build` (standard version) without first running `cargo build --release --target <triple>` for the selected wheel platform — including when LLMFIT_PYTHON_PLATFORM_TAG selects a cross target whose artifact was never produced, or after `cargo clean` removed target/.","commonSituations":"CI release matrix that builds the wheel before the Rust cross-compile step; a developer copying the wheel-building step to a new machine without the cargo step; `cargo clean` between builds; running `rustup target add` but forgetting the actual build for that target.","solutions":["Build the binary for the exact upstream target: `cargo build --release --target x86_64-unknown-linux-gnu` (substitute the triple from the error message / TARGET_CONFIGS)","Add the Rust target toolchain first if missing: `rustup target add aarch64-unknown-linux-gnu`","For local builds where you just want a wheel of the host binary, build for the host and let platform detection pick it, or use an editable install which falls back to target/debug and target/release"],"exampleFix":"# before\nuv build\n# => FileNotFoundError: Binary not found at .../target/aarch64-unknown-linux-gnu/release/llmfit\n\n# after\nrustup target add aarch64-unknown-linux-gnu\ncargo build --release --target aarch64-unknown-linux-gnu\nuv build","handlingStrategy":"validation","validationCode":"import os\nfrom pathlib import Path\nfrom hatch_build import TARGET_CONFIGS\npy_target = os.environ.get(\"LLMFIT_PYTHON_PLATFORM_TAG\", \"manylinux_2_17_x86_64\")\ntriple, name = TARGET_CONFIGS[py_target]\nbin_path = Path(\"target\") / triple / \"release\" / name\nif not bin_path.is_file():\n    raise SystemExit(f\"missing {bin_path} — run `cargo build --release --target {triple}` first\")","typeGuard":null,"tryCatchPattern":"try:\n    bin_path = hook._find_binary_for_target(root, py_target)\nexcept FileNotFoundError as e:\n    raise SystemExit(f\"pre-build rust artifact missing: {e}\")","preventionTips":["Order CI steps: rustup target add -> cargo build --release --target <triple> -> uv build","Fail the cargo step loudly so the wheel step never starts with a missing artifact","After cargo clean, always rebuild before any wheel build"],"tags":["rust","cargo","packaging","build-artifact","cross-compilation"],"backgroundTag":"missing-build-artifact","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"}