langflow-ai/langflow · error · ValueError
Could not read lfx version from src/lfx/pyproject.toml
Error message
Could not read lfx version from src/lfx/pyproject.toml
What it means
port_bundle.py computes the lfx dependency floor/cap for a new bundle (lfx>=X.Y.0.dev0,<(X+1).0.0) by regex-matching a static `version = "<major>.<minor>.<patch>..."` line in src/lfx/pyproject.toml. If the regex does not match — the version line is missing, dynamic, or formatted differently — it raises ValueError('Could not read lfx version from src/lfx/pyproject.toml'). Note: a completely missing file surfaces as FileNotFoundError first; this error specifically means the file was read but its version could not be parsed.
Source
Thrown at scripts/migrate/port_bundle.py:141
def _current_lfx_floor() -> str:
"""Return the ``lfx`` dependency floor for a freshly-ported bundle.
Reads the workspace lfx version from ``src/lfx/pyproject.toml`` and pins
``lfx>=X.Y.0.dev0,<(X+1).0.0`` -- floored at the current major.minor
line's first pre-release (the branch's own canonical ``X.Y.0.devN``
nightlies sort below a plain ``X.Y.0`` under PEP 440, so they must be
admitted by the floor), capped below the next lfx major. Mirrors
``lfx_floor_spec`` in ``scripts/ci/sync_bundle_lfx_pin.py`` (each script
is kept standalone, so keep the two in step); that script re-syncs every
existing bundle on ``make patch``.
"""
lfx_pyproject = (REPO_ROOT / "src" / "lfx" / "pyproject.toml").read_text(encoding="utf-8")
match = re.search(r'^version = "(\d+)\.(\d+)\.\d+', lfx_pyproject, re.MULTILINE)
if not match:
msg = "Could not read lfx version from src/lfx/pyproject.toml"
raise ValueError(msg)
major, minor = int(match.group(1)), int(match.group(2))
return f"lfx>={major}.{minor}.0.dev0,<{major + 1}.0.0"
# ---------------------------------------------------------------------------
# Templates
# ---------------------------------------------------------------------------
PYPROJECT_TEMPLATE = """\
[project]
name = "lfx-{bundle}"
version = "0.1.0"
description = "{display_name} component(s) as a standalone Langflow Extension Bundle."
readme = "README.md"
requires-python = ">=3.10,<3.15"
license = {{ text = "MIT" }}
authors = [View on GitHub (pinned to 976ec789d2)
Solutions
- Ensure src/lfx/pyproject.toml contains a static PEP 621 line like `version = "1.8.0"` at the start of a line (double quotes, three numeric segments).
- If versioning must stay dynamic, temporarily resolve the version (e.g. `hatch version`) and write the static line before running the script, then revert.
- Re-run `python scripts/migrate/port_bundle.py --bundle <name>` and confirm the generated bundle pyproject gets a sane lfx floor.
Example fix
# before (src/lfx/pyproject.toml) [project] name = "lfx" dynamic = ["version"] # after [project] name = "lfx" version = "1.8.0"
Defensive patterns
Strategy: try-catch
Validate before calling
import re
from pathlib import Path
LFX_PYPROJECT = Path("src/lfx/pyproject.toml")
def lfx_version_line_ok() -> bool:
text = LFX_PYPROJECT.read_text(encoding="utf-8")
return re.search(r'^version = "(\d+)\.(\d+)\.\d+', text, re.MULTILINE) is not None Try / catch
try:
port_bundle.main(["--bundle", name, "--apply"])
except ValueError as exc:
if "Could not read lfx version" in str(exc):
# fix src/lfx/pyproject.toml to a static PEP 621 version, then retry once
raise SystemExit("src/lfx/pyproject.toml needs a static version = \"X.Y.Z\" line") from exc
raise Prevention
- Keep a static `version = "X.Y.Z"` line in src/lfx/pyproject.toml; avoid dynamic = ["version"] in this repo.
- Note this script's floor logic is mirrored in scripts/ci/sync_bundle_lfx_pin.py — keep both in mind when changing versioning.
- A missing file raises FileNotFoundError; this message means the file exists but the version line didn't parse.
When it happens
Trigger: Running port_bundle.py when src/lfx/pyproject.toml declares its version dynamically (e.g. `dynamic = ["version"]` with a hatch/setuptools plugin) or the version string starts with something the anchored regex `^version = "(\d+)\.(\d+)\.\d+` cannot match (prefixed letters, single quotes, or a build variable).
Common situations: Downstream forks that switched to dynamic versioning; a reformatting of pyproject.toml (whitespace inside the assignment is tolerated by the regex, but quotes style or `version=` without spaces on a multiline table is not); running the script from a repo state where the lfx package pyproject was refactored.
Related errors
- The '{provider}' components moved to the 'lfx-bundles' distr
- {provider}: source has subdirectory/ies {subdirs} that move_
- {nested} imports from ``langflow`` -- the bundle is installe
- {src} imports from ``langflow`` -- the bundle is installed a
- Could not strip ruff per-file-ignore entry for {ri.pattern!r
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/2133611999bcdb1f.
Report an issue: GitHub.