langflow-ai/langflow · warning · SystemExit
No ``*.py`` files under {in_tree}; nothing to port.
Error message
No ``*.py`` files under {in_tree}; nothing to port. What it means
After scanning the in-tree provider directory, port_bundle.py requires at least one porting unit: either a top-level *.py file or a nested subpackage. If the directory contains no Python files at all (only __pycache__, data files, or nothing), there is nothing to mechanically port and the script exits with 'No *.py files under <path>; nothing to port.'
Source
Thrown at scripts/migrate/port_bundle.py:735
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."
raise SystemExit(msg)
if migration_release is not None and not re.fullmatch(r"\d+\.\d+\.\d+", migration_release):
msg = f"--migration-release {migration_release!r} must be a three-segment SemVer (e.g. 1.10.0)."
raise SystemExit(msg)
resolved_display = display_name if display_name is not None else bundle.replace("_", " ").title()
shared_base = LFX_BASE / bundle
shared_base_dir = shared_base if shared_base.is_dir() else None
backend_test_dirs = _discover_backend_test_dirs(bundle)
ruff_ignores = _discover_ruff_ignores(bundle)
base_extra_present = _discover_base_extra(bundle)
legacy_dynamic, legacy_all = _parse_legacy_init(in_tree / "__init__.py")
consumer_rewrites: tuple[ConsumerRewrite, ...] = ()
if discover_consumers:View on GitHub (pinned to 976ec789d2)
Solutions
- List the directory shown in the error: `ls -la <in-tree path>` to confirm it is empty of *.py.
- If it is debris, delete the directory instead of porting it.
- If modules should exist, restore them from git (`git checkout <ref> -- <dir>`) and re-run.
Example fix
# before ls src/lfx/src/lfx/components/legacy # only __pycache__ python scripts/migrate/port_bundle.py --bundle legacy # error: No ``*.py`` files under ...; nothing to port. # after git rm -r src/lfx/src/lfx/components/legacy # remove debris instead of porting
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def has_portable_units(provider_dir: Path) -> bool:
top = any(p.suffix == ".py" for p in provider_dir.iterdir())
nested = any(p.is_dir() and p.name != "__pycache__" for p in provider_dir.iterdir())
return top or nested Prevention
- Delete empty provider directories as debris instead of trying to port them.
- If modules are expected but missing, restore from git before running the script.
When it happens
Trigger: Running port_bundle.py --bundle <name> on an emptied or never-populated provider directory — e.g. one whose modules were already deleted in a prior cleanup but whose folder remained.
Common situations: Leftover empty directories after a partial migration; placeholder provider dirs; files with wrong extensions (.py.txt) after a bad merge.
Related errors
- provider directory not found: {src}
- In-tree provider directory not found: {in_tree}
- destination already exists (already consolidated?): {dst}
- --bundle {bundle!r} is not a valid bundle name (lowercase sn
- Bundle directory already exists: {bundle_dir}. Refusing to
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/61763d54eb46d181.
Report an issue: GitHub.