langflow-ai/langflow · error · SystemExit
{nested} imports from ``langflow`` -- the bundle is installe
Error message
{nested} imports from ``langflow`` -- the bundle is installed against the public BUNDLE_API surface (lfx), not Langflow internals. Either rewrite the import or leave the component in-tree. See src/bundles/PORTING.md § 0. What it means
During eligibility scanning, port_bundle.py walks every *.py file — including files inside nested subpackages (rglob, skipping __pycache__) — and rejects any file containing the literal text 'from langflow'. Out-of-tree bundles must depend only on the public lfx BUNDLE_API surface, not Langflow-internal imports, because the published lfx-<bundle> distribution cannot depend on the langflow package. Hitting this text in a nested file aborts the port with the file path and a pointer to PORTING.md § 0.
Source
Thrown at scripts/migrate/port_bundle.py:716
for src in sorted(in_tree.iterdir()):
if src.is_dir():
if src.name == "__pycache__":
continue
# Nested subpackage (e.g. ``agentics/helpers``); validate
# its files for ``from langflow`` imports too, then plan
# to move the whole subdir wholesale.
for nested in src.rglob("*.py"):
if "__pycache__" in nested.parts:
continue
text = nested.read_text(encoding="utf-8")
if "from langflow" in text:
msg = (
f"{nested} imports from ``langflow`` -- the bundle is "
"installed against the public BUNDLE_API surface (lfx), "
"not Langflow internals. Either rewrite the import or "
"leave the component in-tree. See src/bundles/PORTING.md § 0."
)
raise SystemExit(msg)
nested_subdirs.append(src)
continue
if not src.is_file() or src.suffix != ".py":
continue
text = src.read_text(encoding="utf-8")
if "from langflow" in text:
msg = (
f"{src} imports from ``langflow`` -- the bundle is installed "
"against the public BUNDLE_API surface (lfx), not Langflow "
"internals. Either rewrite the import or leave the component "
"in-tree. See src/bundles/PORTING.md § 0."
)
raise SystemExit(msg)
classes = () if src.name == "__init__.py" else _discover_classes(text)
component_files.append(ComponentFile(path=src, classes=classes))
if not component_files and not nested_subdirs:
msg = f"No ``*.py`` files under {in_tree}; nothing to port."View on GitHub (pinned to 976ec789d2)
Solutions
- Open the named file and rewrite `from langflow.X` to the lfx equivalent (usually `from lfx.X`) using the public BUNDLE_API surface.
- If the import has no lfx equivalent, the component cannot be ported — leave it in-tree and port only the rest, or refactor the dependency out.
- Remove literal 'from langflow' occurrences from comments/docstrings (the check is textual).
Example fix
# before (helpers/utils.py) from langflow.logging import logger # after (helpers/utils.py) from lfx.logging import logger
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def clean_of_langflow_imports(provider_dir: Path) -> list[Path]:
"""Mirror of the port guard: list offending files (nested included)."""
return [
p for p in provider_dir.rglob("*.py")
if "__pycache__" not in p.parts and "from langflow" in p.read_text(encoding="utf-8")
]
assert not clean_of_langflow_imports(LFX_COMPONENTS / bundle) Prevention
- Run a repo-wide grep for 'from langflow' inside the provider dir before invoking port_bundle.py — the guard is a literal substring match, comments included.
- Bundles may only use the lfx BUNDLE_API; if an import has no lfx equivalent the component stays in-tree.
- Rewrite imports to lfx.* equivalents in a separate commit before the port commit so diffs stay reviewable.
When it happens
Trigger: Running port_bundle.py --bundle <name> where any module inside a nested subpackage (e.g. <provider>/helpers/utils.py) has `from langflow.xxx import ...`. The check is a literal substring match, so even a commented-out or docstring occurrence triggers it.
Common situations: Older components written against the langflow package before the lfx split; helper utilities importing langflow.logging or schema internals; stale comments mentioning 'from langflow' after the code was already migrated.
Related errors
- {src} imports from ``langflow`` -- the bundle is installed a
- error: {source} entries field must be a list
- error: {source} ambiguous_bare_names field must be a list
- The '{provider}' components moved to the 'lfx-bundles' distr
- provider directory not found: {src}
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/a503ddafed6e1aab.
Report an issue: GitHub.