{"record":{"id":"66ed3ae95fa7cc06","repo":"langflow-ai/langflow","slug":"bundle-directory-already-exists-bundle-dir-re","errorCode":null,"errorMessage":"Bundle directory already exists: {bundle_dir}.  Refusing to overwrite.","messagePattern":"Bundle directory already exists: (.+?)\\.  Refusing to overwrite\\.","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"warning","filePath":"scripts/migrate/port_bundle.py","lineNumber":685,"sourceCode":") -> PortPlan:\n    \"\"\"Refuse early if the candidate is not eligible for the mechanical port.\"\"\"\n    if not re.fullmatch(r\"[a-z][a-z0-9_]{1,63}\", bundle):\n        msg = (\n            f\"--bundle {bundle!r} is not a valid bundle name (lowercase \"\n            \"snake_case, 2-64 chars, starts with a letter).  This script \"\n            \"ports an in-tree provider folder named exactly the same.\"\n        )\n        raise SystemExit(msg)\n\n    in_tree = LFX_COMPONENTS / bundle\n    if not in_tree.is_dir():\n        msg = f\"In-tree provider directory not found: {in_tree}\"\n        raise SystemExit(msg)\n\n    bundle_dir = BUNDLES_DIR / bundle\n    if bundle_dir.exists():\n        msg = f\"Bundle directory already exists: {bundle_dir}.  Refusing to overwrite.\"\n        raise SystemExit(msg)\n\n    deactivated_dup = LFX_COMPONENTS / \"deactivated\" / bundle\n    if deactivated_dup.is_dir():\n        msg = (\n            f\"A deactivated duplicate exists at {deactivated_dup}.  Resolve \"\n            \"the duplicate manually before porting -- see \"\n            \"src/bundles/PORTING.md § 0.\"\n        )\n        raise SystemExit(msg)\n\n    component_files: list[ComponentFile] = []\n    nested_subdirs: list[Path] = []\n    for src in sorted(in_tree.iterdir()):\n        if src.is_dir():\n            if src.name == \"__pycache__\":\n                continue\n            # Nested subpackage (e.g. ``agentics/helpers``); validate\n            # its files for ``from langflow`` imports too, then plan","sourceCodeStart":667,"sourceCodeEnd":703,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/scripts/migrate/port_bundle.py#L667-L703","documentation":"Third guard in port_bundle.py's eligibility check: the destination BUNDLES_DIR/<bundle> must not already exist. The script refuses to overwrite an existing bundle directory because a re-run would interleave with the previous port's files, migrations, and workspace registration. Exit with 'Bundle directory already exists: <path>. Refusing to overwrite.'","triggerScenarios":"Re-running port_bundle.py for a bundle that was already ported (destination committed or left over from an aborted run); a name collision with a hand-created bundle scaffold.","commonSituations":"Retry after an interrupted --apply; running the port twice because the first run's output was missed; leftover directories from a reverted PR.","solutions":["If the earlier port completed, don't re-port — continue from its state or amend it directly.","If it's debris from an aborted run, remove the destination directory (and any workspace/pyproject registrations it made) and re-run from clean: `git clean -fd src/bundles/` after reviewing `git status`.","Never point --bundle at an existing bundle expecting an in-place update; the script is create-only by design."],"exampleFix":"# before\npython scripts/migrate/port_bundle.py --bundle agentics --apply  # second attempt\n# error: Bundle directory already exists: src/bundles/agentics. Refusing to overwrite.\n\n# after\ngit status src/bundles/agentics  # decide: keep prior port, or:\nrm -rf src/bundles/agentics && git checkout -- pyproject.toml && python scripts/migrate/port_bundle.py --bundle agentics --apply","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\nBUNDLES_DIR = Path(\"src/bundles\")\n\ndef bundle_absent(bundle: str) -> bool:\n    return not (BUNDLES_DIR / bundle).exists()","typeGuard":null,"tryCatchPattern":null,"preventionTips":["The script is create-only; never re-run against an existing bundle directory expecting an update.","Clean aborted runs fully (bundle dir + pyproject/workspace registrations) before retrying, ideally via git clean/checkout."],"tags":["migration","idempotency","filesystem","cli"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}