langflow-ai/langflow · error · UserComponentError
class_name must be a CamelCase identifier (letters/digits/un
Error message
class_name must be a CamelCase identifier (letters/digits/underscores, leading uppercase). Got: {class_name!r} What it means
Raised when the proposed component class name fails the strict identifier regex ^[A-Z][A-Za-z0-9_]*$ (fullmatch). Langflow requires the name to be a valid Python identifier starting with an uppercase letter so the same string works both as a class name at import time and as a file stem in the registry overlay. This rejects '.', '..', leading dots/underscores, dunders, snake_case names, and any non-alphanumeric characters.
Source
Thrown at src/backend/base/langflow/agentic/services/user_components.py:230
raise UserComponentError(msg)
# Windows-portability path-length cap. Checked BEFORE other rules so
# the error message is specific and the rest of the validator never
# has to reason about pathological inputs.
if len(class_name) > MAX_CLASS_NAME_LENGTH:
msg = f"class_name length {len(class_name)} exceeds max {MAX_CLASS_NAME_LENGTH} (Windows MAX_PATH safeguard)"
raise UserComponentError(msg)
# Filesystem-portability guard (rejects NUL, Windows-forbidden punct,
# path separators, dotdot, control chars, trailing dot/space, etc.).
if err := _check_windows_portability(class_name):
raise UserComponentError(err)
# Reject `.`, `..`, leading dots, leading underscores, dunders, and
# anything that isn't a valid CamelCase identifier.
if not _CLASS_NAME_RE.fullmatch(class_name):
msg = (
f"class_name must be a CamelCase identifier "
f"(letters/digits/underscores, leading uppercase). Got: {class_name!r}"
)
raise UserComponentError(msg)
if class_name.upper() in _WINDOWS_RESERVED_DEVICES:
msg = f"class_name {class_name!r} is a Windows-reserved device name"
raise UserComponentError(msg)
def _validate_code(code: str) -> None:
if not code or not code.strip():
msg = "code must be a non-empty string"
raise UserComponentError(msg)
encoded_size = len(code.encode("utf-8"))
if encoded_size > MAX_COMPONENT_SOURCE_BYTES:
msg = f"code size {encoded_size} bytes exceeds limit of {MAX_COMPONENT_SOURCE_BYTES} bytes"
raise UserComponentError(msg)
def _resolve_components_dir(*, user_id: str | None) -> Path:
"""Resolve and create ``<sandbox>/.components/`` for the given user.
View on GitHub (pinned to 976ec789d2)
Solutions
- Rename to CamelCase starting with an uppercase letter: 'MyComponent', 'DataLoader', 'Agent1'.
- Underscores are allowed but not at the start; convert 'data_loader' to 'DataLoader'.
- Update the generation prompt to enforce PEP 8 class naming for the emitted class.
Example fix
# before register_user_component(user_id=uid, class_name="data_loader", code=src) # after register_user_component(user_id=uid, class_name="DataLoader", code=src)
Defensive patterns
Strategy: validation
Validate before calling
import re
_CAMEL = re.compile(r"^[A-Z][A-Za-z0-9_]*$")
def check_class_name(name: str) -> str | None:
"""Return None if valid, else a human-readable problem."""
if not name:
return "empty"
if not _CAMEL.fullmatch(name):
return f"{name!r} is not CamelCase (uppercase first letter, letters/digits/underscores only)"
return None Type guard
def is_camel_case_class(name: str) -> TypeGuard[str]:
return bool(re.fullmatch(r"[A-Z][A-Za-z0-9_]*", name or "")) Try / catch
try:
register_user_component(user_id=uid, class_name=name, code=src)
except UserComponentError as e:
if "CamelCase" in str(e):
name = "".join(w.capitalize() for w in re.split(r"[^A-Za-z0-9]+", name) if w)
register_user_component(user_id=uid, class_name=name, code=src) Prevention
- Convert snake_case to CamelCase programmatically before registering.
- Add a naming rule to the generation prompt and validate the emitted name before the registration hook.
When it happens
Trigger: register_user_component with class_name like 'my_component' (lowercase start), '_Private', '__dunder__', 'Agent-1', or an empty string (empty is caught earlier by the non-empty check, but whitespace-only or malformed names land here).
Common situations: Model-generated code using snake_case class names; names prefixed with underscore for 'private' components; hyphenated names copied from a title or filename like 'Data-Loader'.
Related errors
- err
- class_name {class_name!r} is a Windows-reserved device name
- code must be a non-empty string
- code size {encoded_size} bytes exceeds limit of {MAX_COMPONE
- Failed to install MCP
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/d08e24289c445f37.
Report an issue: GitHub.