{"record":{"id":"d867195fad9b9f63","repo":"AlexsJones/llmfit","slug":"unexpected-output-from-bin-path-version-ou","errorCode":null,"errorMessage":"Unexpected output from '{bin_path} --version': {output!r}","messagePattern":"Unexpected output from '(.+?) --version': (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"llmfit-python/hatch_build.py","lineNumber":155,"sourceCode":"        )\n\n    @staticmethod\n    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()","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/AlexsJones/llmfit/blob/acc7e40c3a0afbd36510a92f2f8f3d5177cfc0fe/llmfit-python/hatch_build.py#L137-L173","documentation":"Raised by LlmfitBinaryBuildHook._check_binary_version(), which executes the packaged binary with `--version` and requires the stripped stdout to match exactly `llmfit X.Y.Z` or `llmfit vX.Y.Z` (regex ^llmfit v?(\\d+\\.\\d+\\.\\d+)$). Any additional output on stdout — a commit hash, feature list, log line, or debug print — makes the match fail and raises this RuntimeError. Note the check only runs when the binary's platform matches the build host, and check=True would raise CalledProcessError instead for a nonzero exit.","triggerScenarios":"The binary's `--version` output format drifts: someone adds build metadata (e.g. 'llmfit 0.9.8+abc1234' or 'llmfit 0.9.8 (debug)'), a library starts printing logs to stdout before clap formats the version, or a locally modified binary prints extra lines. Then any wheel build on that host fails.","commonSituations":"Changing the clap version string or adding startup banner output in llmfit-tui; building a wheel against a development binary with eprintln/println instrumentation; a distro-patched binary with branded version output.","solutions":["Run `./target/release/llmfit --version` yourself and compare against the expected 'llmfit X.Y.Z' shape; remove any extra stdout output from the version path","Rebuild the binary from a clean checkout (`make build`) in case a locally instrumented binary is being picked up","If the richer version string is intentional, relax the regex in hatch_build.py to tolerate trailing text: r\"^llmfit v?(\\d+\\.\\d+\\.\\d+)(?:\\s.*)?$\""],"exampleFix":"# before (hatch_build.py)\nmatch = re.match(r\"^llmfit v?(\\d+\\.\\d+\\.\\d+)$\", output)\n\n# after — tolerate trailing build metadata\nmatch = re.match(r\"^llmfit v?(\\d+\\.\\d+\\.\\d+)(?:\\s.*)?$\", output)","handlingStrategy":"validation","validationCode":"import re, subprocess, sys\nout = subprocess.run([\"./target/release/llmfit\", \"--version\"], capture_output=True, text=True, timeout=5).stdout.strip()\nif not re.fullmatch(r\"llmfit v?\\d+\\.\\d+\\.\\d+\", out):\n    raise SystemExit(f\"unexpected --version output {out!r} — fix binary output before packaging\")","typeGuard":null,"tryCatchPattern":"try:\n    hook._check_binary_version(bin_path, expected)\nexcept RuntimeError as e:\n    raise SystemExit(f\"version probe failed: {e}\")","preventionTips":["Keep the --version output exactly 'llmfit X.Y.Z'; put any extra banner on stderr or behind a flag","Add a CLI integration test asserting the --version format so drift is caught in CI","Never println! diagnostics in the binary before clap parses --version"],"tags":["python","rust","version-check","packaging","cli-output"],"backgroundTag":"cli-version-parse-failed","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"}