{"record":{"id":"b8a06caa3843fe51","repo":"langflow-ai/langflow","slug":"src-imports-from-langflow-the-bundle-is-i","errorCode":null,"errorMessage":"{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.","messagePattern":"(.+?) 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\\.","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"scripts/migrate/port_bundle.py","lineNumber":729,"sourceCode":"                        f\"{nested} imports from ``langflow`` -- the bundle is \"\n                        \"installed against the public BUNDLE_API surface (lfx), \"\n                        \"not Langflow internals.  Either rewrite the import or \"\n                        \"leave the component in-tree.  See src/bundles/PORTING.md § 0.\"\n                    )\n                    raise SystemExit(msg)\n            nested_subdirs.append(src)\n            continue\n        if not src.is_file() or src.suffix != \".py\":\n            continue\n        text = src.read_text(encoding=\"utf-8\")\n        if \"from langflow\" in text:\n            msg = (\n                f\"{src} imports from ``langflow`` -- the bundle is installed \"\n                \"against the public BUNDLE_API surface (lfx), not Langflow \"\n                \"internals.  Either rewrite the import or leave the component \"\n                \"in-tree.  See src/bundles/PORTING.md § 0.\"\n            )\n            raise SystemExit(msg)\n        classes = () if src.name == \"__init__.py\" else _discover_classes(text)\n        component_files.append(ComponentFile(path=src, classes=classes))\n\n    if not component_files and not nested_subdirs:\n        msg = f\"No ``*.py`` files under {in_tree}; nothing to port.\"\n        raise SystemExit(msg)\n\n    if migration_release is not None and not re.fullmatch(r\"\\d+\\.\\d+\\.\\d+\", migration_release):\n        msg = f\"--migration-release {migration_release!r} must be a three-segment SemVer (e.g. 1.10.0).\"\n        raise SystemExit(msg)\n\n    resolved_display = display_name if display_name is not None else bundle.replace(\"_\", \" \").title()\n\n    shared_base = LFX_BASE / bundle\n    shared_base_dir = shared_base if shared_base.is_dir() else None\n\n    backend_test_dirs = _discover_backend_test_dirs(bundle)\n    ruff_ignores = _discover_ruff_ignores(bundle)","sourceCodeStart":711,"sourceCodeEnd":747,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/scripts/migrate/port_bundle.py#L711-L747","documentation":"Identical guard to error 54, but for top-level provider modules rather than nested subpackage files: port_bundle.py reads every top-level *.py under the in-tree provider dir and refuses the port if any contains 'from langflow'. Bundles are distributed standalone against lfx, so a Langflow-internal import makes the module unportable as-is; the error names the offending file and defers to PORTING.md § 0.","triggerScenarios":"Running port_bundle.py on a provider where a top-level module (e.g. <provider>/model.py) still does `from langflow.field_typing import ...` or any other langflow import. Like 54, the detection is a raw substring test on the file text.","commonSituations":"Pre-lfx-split component code; partially migrated providers where most files were converted but one was missed; false positives from comments containing the phrase.","solutions":["Rewrite the import in the named file to its lfx counterpart (e.g. langflow.custom -> lfx.custom, langflow.io -> lfx.io, langflow.schema -> lfx.schema).","Grep the whole provider dir first: `grep -rn 'from langflow' <in-tree dir>` to fix all hits in one pass.","Re-run the port; the guard re-checks every file each time."],"exampleFix":"# before (openai/model.py)\nfrom langflow.io import Output, StrInput\n\n# after (openai/model.py)\nfrom lfx.io import Output, StrInput","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef top_level_langflow_imports(provider_dir: Path) -> list[Path]:\n    return [\n        p for p in sorted(provider_dir.glob(\"*.py\"))\n        if \"from langflow\" in p.read_text(encoding=\"utf-8\")\n    ]","typeGuard":null,"tryCatchPattern":null,"preventionTips":["grep -rn 'from langflow' <provider dir> and fix every hit (code, comments, docstrings) before porting.","Map langflow.* imports to their lfx.* counterparts (custom, io, schema, logging) as part of pre-port cleanup."],"tags":["migration","imports","packaging","validation"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}