crewAIInc/crewAI · error · ValueError

Project name '{name}' would generate class name '{class_name

Error message

Project name '{name}' would generate class name '{class_name}' which is a reserved Python keyword

What it means

Raised by ContextualRerankTool._run when a metadata list is supplied whose length differs from the documents list. The rerank API expects metadata[i] to annotate documents[i], so the tool validates len(metadata) == len(documents) before building the payload and raises ValueError on mismatch.

Source

Thrown at lib/cli/src/crewai_cli/create_crew.py:115

    if not class_name:
        raise ValueError(
            f"Project name '{name}' contains no valid characters for a Python class name"
        )

    if class_name[0].isdigit():
        raise ValueError(
            f"Project name '{name}' would generate class name '{class_name}' which cannot start with a digit"
        )

    original_name_clean = re.sub(
        r"[^a-zA-Z0-9_]", "", name.replace("_", "").replace("-", "").lower()
    )
    if (
        keyword.iskeyword(original_name_clean)
        or keyword.iskeyword(class_name)
        or class_name in ("True", "False", "None")
    ):
        raise ValueError(
            f"Project name '{name}' would generate class name '{class_name}' which is a reserved Python keyword"
        )

    if not class_name.isidentifier():
        raise ValueError(
            f"Project name '{name}' would generate invalid Python class name '{class_name}'"
        )

    if parent_folder:
        folder_path = Path(parent_folder) / folder_name
    else:
        folder_path = Path(folder_name)

    if folder_path.exists():
        if is_dmn_mode_enabled():
            raise click.ClickException(f"Folder {folder_name} already exists.")
        if not click.confirm(
            f"Folder {folder_name} already exists. Do you want to override it?"

View on GitHub (pinned to 754d7323be)

Solutions

  1. Build metadata and documents in one pass so they stay aligned: pairs = [(doc, meta) for ...]; docs, metas = zip(*pairs).
  2. If metadata is optional, drop it entirely instead of passing a partial list.
  3. Add an assert len(metadata) == len(documents) right where the two lists are assembled.

Example fix

# before
result = tool._run(query=q, documents=docs, metadata=metas)  # lengths differ -> ValueError
# after
assert len(docs) == len(metas), f'{len(docs)} docs vs {len(metas)} metadata'
result = tool._run(query=q, documents=docs, metadata=metas)
Defensive patterns

Strategy: validation

Validate before calling

if metadata is not None:
    assert len(metadata) == len(documents), (
        f"{len(documents)} documents vs {len(metadata)} metadata entries"
    )
result = tool._run(query=query, documents=documents, metadata=metadata)

Prevention

When it happens

Trigger: Calling _run(documents=[d1, d2, d3], metadata=[m1, m2]) — e.g. metadata collected only for documents that passed a filter, or documents appended after metadata was built.

Common situations: Chunking pipelines where document chunks are regenerated but cached metadata is reused, filtering one list but not the other, or off-by-one when pairing sources to chunks.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/7a31043cd6efbb52. Report an issue: GitHub.