AlexsJones/llmfit · error · ValueError
Invalid version: {version!r}
Error message
Invalid version: {version!r} What it means
LlmfitMetadataHook.update() resolves the Python package version: the LLMFIT_VERSION environment variable wins, otherwise [workspace.package].version from the repo-root Cargo.toml. It must match ^\d+\.\d+\.\d+$ exactly (plain MAJOR.MINOR.PATCH); anything else aborts wheel metadata resolution with this ValueError, which fails uv build, uv sync, and pip builds of llmfit-python.
Source
Thrown at llmfit-python/hatch_build.py:74
PLUGIN_NAME = "llmfit version, license and readme"
def update(self, metadata: dict) -> None:
"""Populate dynamic metadata from the repository.
``version`` and ``license-expression`` come from ``Cargo.toml``,
``readme`` from the repository root.
Version resolution order:
1. ``LLMFIT_VERSION`` environment variable (e.g. ``0.9.8``).
2. The ``version`` field in ``[workspace.package]`` from ``Cargo.toml``.
"""
with (Path(self.root).parent / "Cargo.toml").open("rb") as f:
workspace_package: dict[str, str] = tomli.load(f)["workspace"]["package"]
version: str = os.environ.get("LLMFIT_VERSION") or workspace_package["version"]
if not re.match(r"^\d+\.\d+\.\d+$", version):
raise ValueError(f"Invalid version: {version!r}")
metadata["version"] = version
metadata["license-expression"] = workspace_package["license"]
# The package README is the repository one. Hatchling refuses a
# `readme = "../README.md"` path ("must be within the project
# directory") but takes the contents verbatim, so read it here rather
# than duplicating or symlinking the file.
readme = Path(self.root).parent / "README.md"
metadata["readme"] = {
"content-type": "text/markdown",
"text": readme.read_text(encoding="utf-8"),
}
class LlmfitBinaryBuildHook(BuildHookInterface):
"""Hatchling build hook that injects the llmfit binary into each wheel."""
PLUGIN_NAME = "llmfit binary"View on GitHub (pinned to a9ac7ed91c)
Solutions
- Echo $LLMFIT_VERSION and strip anything beyond MAJOR.MINOR.PATCH (drop 'v', suffixes, whitespace) or unset it: `unset LLMFIT_VERSION`.
- If the version comes from Cargo.toml, set [workspace.package] version to a plain semver triplet and keep release identifiers elsewhere.
- In CI, normalize before export: LLMFIT_VERSION=$(git describe --tags | sed -E 's/^v?([0-9]+\.[0-9]+\.[0-9]+).*$/\1/').
- Verify with `python -c "import re,sys; print(bool(re.match(r'^\d+\.\d+\.\d+$', sys.argv[1])))" "$LLMFIT_VERSION"` before invoking the build.
Example fix
# before export LLMFIT_VERSION="v0.9.8-rc.1" uv build # after export LLMFIT_VERSION="0.9.8" uv build
Defensive patterns
Strategy: validation
Validate before calling
import os, re
version = os.environ.get('LLMFIT_VERSION') or read_cargo_version()
if not re.match(r'^\d+\.\d+\.\d+$', version):
version = re.search(r'\d+\.\d+\.\d+', version).group(0) # normalize, or fail loudly
assert re.match(r'^\d+\.\d+\.\d+$', version), f'bad version {version!r}' Try / catch
try:
subprocess.run(['uv', 'build'], check=True, env=env)
except subprocess.CalledProcessError as e:
if 'Invalid version:' in (e.stderr or ''):
fix_and_retry_with_normalized_LLMFIT_VERSION() # strip 'v', suffixes, whitespace
raise Prevention
- Normalize version strings to plain MAJOR.MINOR.PATCH at the point they enter CI (git describe, release vars).
- Keep [workspace.package].version in Cargo.toml a bare semver triplet; track pre-release state elsewhere.
- Echo LLMFIT_VERSION in build logs before the build step so mismatches are visible.
- Unset LLMFIT_VERSION in local shells after release experiments.
When it happens
Trigger: Exporting LLMFIT_VERSION=0.9.8-rc.1 or 0.9.8+dev before building the wheel; bumping Cargo.toml's workspace version to a prerelease form like 0.10.0-rc.1; an LLMFIT_VERSION with a leading 'v' or trailing whitespace/newline from a CI step; an empty LLMFIT_VERSION string is falsy and falls through, but a malformed non-empty one always trips this.
Common situations: CI pipelines deriving LLMFIT_VERSION from a git tag (v1.2.3 keeps the 'v', 1.2.3-rc.1 keeps the suffix); release automation setting a pre-release identifier that Python allows but this strict regex forbids; a stale env var left in a shell from an earlier experiment.
Related errors
- Unexpected output from '{bin_path} --version': {output!r}
- No suitable wheel platform found for runtime platform {first
- Binary not found at {bin_path}. Expected it to be built for
- Binary version mismatch: binary at {bin_path} reports {binar
- LLMFIT_PYTHON_PLATFORM_TAG is not supported for editable ins
AI-assisted analysis of AlexsJones/llmfit@a9ac7ed91c (2026-08-16).
Data as JSON: /api/errors/ae200507b967eafb.
Report an issue: GitHub.