langflow-ai/langflow · error · SystemExit

--bundle {bundle!r} is not a valid bundle name (lowercase sn

Error message

--bundle {bundle!r} is not a valid bundle name (lowercase snake_case, 2-64 chars, starts with a letter).  This script ports an in-tree provider folder named exactly the same.

What it means

The first eligibility guard in port_bundle.py's planning phase: the --bundle argument must fullmatch the regex [a-z][a-z0-9_]{1,63} — lowercase snake_case, 2-64 characters, starting with a letter — because the script only ports an in-tree provider folder named exactly the same, and the name becomes a Python package name and ext:<slug> id. Anything else (hyphens, uppercase, digits first, too long) aborts with SystemExit before any work is done.

Source

Thrown at scripts/migrate/port_bundle.py:675

    text = BASE_PYPROJECT.read_text(encoding="utf-8")
    return bool(re.search(rf"^{re.escape(bundle)}\s*=\s*\[", text, re.MULTILINE))


def _validate_candidate(
    bundle: str,
    *,
    display_name: str | None,
    migration_release: str | None,
    discover_consumers: bool,
) -> PortPlan:
    """Refuse early if the candidate is not eligible for the mechanical port."""
    if not re.fullmatch(r"[a-z][a-z0-9_]{1,63}", bundle):
        msg = (
            f"--bundle {bundle!r} is not a valid bundle name (lowercase "
            "snake_case, 2-64 chars, starts with a letter).  This script "
            "ports an in-tree provider folder named exactly the same."
        )
        raise SystemExit(msg)

    in_tree = LFX_COMPONENTS / bundle
    if not in_tree.is_dir():
        msg = f"In-tree provider directory not found: {in_tree}"
        raise SystemExit(msg)

    bundle_dir = BUNDLES_DIR / bundle
    if bundle_dir.exists():
        msg = f"Bundle directory already exists: {bundle_dir}.  Refusing to overwrite."
        raise SystemExit(msg)

    deactivated_dup = LFX_COMPONENTS / "deactivated" / bundle
    if deactivated_dup.is_dir():
        msg = (
            f"A deactivated duplicate exists at {deactivated_dup}.  Resolve "
            "the duplicate manually before porting -- see "
            "src/bundles/PORTING.md § 0."
        )

View on GitHub (pinned to 976ec789d2)

Solutions

  1. Use the exact in-tree provider directory name: `ls src/lfx/src/lfx/components` (LFX_COMPONENTS) and pass that folder name verbatim.
  2. Convert kebab/display names to snake_case: 'open-ai' -> 'openai', 'My Provider' -> 'my_provider'.
  3. If the provider genuinely needs a different bundle name, rename the in-tree directory first (with all import updates), then port.

Example fix

# before
python scripts/migrate/port_bundle.py --bundle open-ai
# error: --bundle 'open-ai' is not a valid bundle name ...

# after
python scripts/migrate/port_bundle.py --bundle openai
Defensive patterns

Strategy: validation

Validate before calling

import re

def valid_bundle_name(name: str) -> bool:
    return re.fullmatch(r"[a-z][a-z0-9_]{1,63}", name) is not None

assert valid_bundle_name(bundle), "--bundle must be lowercase snake_case, 2-64 chars, letter-first"

Type guard

import re

def is_bundle_name(name: str) -> bool:
    """Matches port_bundle.py's eligibility regex exactly."""
    return bool(re.fullmatch(r"[a-z][a-z0-9_]{1,63}", name))

Prevention

When it happens

Trigger: Running port_bundle.py with `--bundle open-ai`, `--bundle OpenAI`, `--bundle 1bundle`, or a 65+ character name. The name is also required to match an existing in-tree directory, so any stylistic deviation is rejected up front.

Common situations: Translating a display name ('Open AI') or PyPI distribution name ('lfx-open-ai') into the bundle argument instead of the directory name; assuming kebab-case is accepted because other tooling in the repo uses it.

Related errors


AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14). Data as JSON: /api/errors/57a953afc1c00611. Report an issue: GitHub.