langflow-ai/langflow · error · UserComponentError
code must be a non-empty string
Error message
code must be a non-empty string
What it means
Raised by _validate_code when the component source code is None-equivalent, empty, or only whitespace. A .components/<ClassName>.py file with no code would produce a broken module for the registry overlay to import, so registration is refused up front.
Source
Thrown at src/backend/base/langflow/agentic/services/user_components.py:239
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.
Reuses the FS tool's authoritative sandbox resolver so the hash
function, pepper handling, AUTO_LOGIN dispatch, and no-user refusal
stay in one place. The reserved-segment guard does NOT apply here —
this helper is the privileged writer that the guard is protecting.
"""
component = FileSystemToolComponent()
if user_id is not None:
component._user_id = user_id # noqa: SLF001 — privileged binding seam
try:View on GitHub (pinned to 976ec789d2)
Solutions
- Check the generated code is non-empty (code and code.strip()) before calling register_user_component.
- If code arrived empty from the model, retry generation instead of registering.
- Prefer register_user_component_if_valid, which swallows this input refusal and returns None.
Example fix
# before
register_user_component(user_id=uid, class_name="MyTool", code=generated) # generated == ""
# after
if generated and generated.strip():
register_user_component(user_id=uid, class_name="MyTool", code=generated) Defensive patterns
Strategy: validation
Validate before calling
def has_component_code(code: str | None) -> bool:
return isinstance(code, str) and bool(code.strip()) Type guard
def is_nonempty_source(code: str | None) -> TypeGuard[str]:
return isinstance(code, str) and len(code.strip()) > 0 Try / catch
try:
register_user_component(user_id=uid, class_name=name, code=code)
except UserComponentError as e:
if "non-empty" in str(e):
skip_registration() # regenerate instead of registering Prevention
- Gate the registration hook on a non-empty, stripped code buffer.
- Use register_user_component_if_valid when best-effort behavior is acceptable — it swallows input refusals and returns None.
When it happens
Trigger: Calling register_user_component with code='', code=' \n', or passing None; typically from an orchestrator wiring mistake where the streamed code buffer was never filled before the registration hook fired.
Common situations: Streaming loop registering the component before the code finished accumulating; a generation step returned an empty string (model refusal or truncation at the seam) and the caller did not check it.
Related errors
- err
- class_name must be a CamelCase identifier (letters/digits/un
- class_name {class_name!r} is a Windows-reserved device name
- 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/ac489a4888960eef.
Report an issue: GitHub.