pathwaycom/pathway · error · ValueError

{role} {col._name!r} must be of type str, got {col._column.d

Error message

{role} {col._name!r} must be of type str, got {col._column.dtype!r}.

What it means

The LEANN sink stores text and metadata as strings, so every column designated as text or metadata must have Pathway dtype pw.STR (dt.STR). _check_str_column raises ValueError naming the offending role ('text_column' or 'metadata column'), the column name, and the actual dtype when this contract is broken.

Source

Thrown at python/pathway/io/leann/__init__.py:128

        self.index_path.parent.mkdir(parents=True, exist_ok=True)
        builder.build_index(str(self.index_path))
        logger.info(
            f"LEANN index built at {self.index_path} with {len(self.documents)} documents"
        )


def _check_leann_available() -> None:
    """Check if leann package is available and raise helpful error if not."""
    try:
        import leann  # noqa: F401
    except ImportError as e:
        raise ImportError(_LEANN_INSTALL_ERROR_MESSAGE) from e


def _check_str_column(col: ColumnReference, role: str) -> None:
    """Raise ValueError if *col* is not of type str."""
    if col._column.dtype != dt.STR:
        raise ValueError(
            f"{role} {col._name!r} must be of type str, " f"got {col._column.dtype!r}."
        )


@check_arg_types
@trace_user_frame
def write(
    table: Table,
    index_path: str | os.PathLike,
    text_column: ColumnReference,
    *,
    metadata_columns: list[ColumnReference] | None = None,
    backend_name: Literal["hnsw", "diskann"] = "hnsw",
    embedding_mode: (
        Literal["sentence-transformers", "openai", "mlx", "ollama"] | None
    ) = None,
    embedding_model: str | None = None,
    embedding_options: dict | None = None,

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Cast the column to string before writing: table.col.astype(str) or table.select(txt=pw.this.col.astype(pw.ColumnSchema(dtype=pw.STR)))
  2. Ensure the read schema declares the column as str (class X(Schema): col: str)
  3. Only pass columns you truly need as metadata, converting numeric ids with apply(lambda x: str(x), dtype=pw.STR-like typing)

Example fix

# before
pw.io.leann.write(t, "idx", t.text, metadata_columns=[t.doc_id])  # doc_id is int

# after
t = t.with_columns(doc_id=t.doc_id.astype(str))
pw.io.leann.write(t, "idx", t.text, metadata_columns=[t.doc_id])
Defensive patterns

Strategy: type-guard

Validate before calling

def is_str_column(col: pw.ColumnReference) -> bool:
    return col._column.dtype == pw.dt.STR

assert is_str_column(table.text) and all(is_str_column(c) for c in metadata_columns)

Type guard

from pathway import dt

def is_str_column(col: pw.ColumnReference) -> bool:
    return col._column.dtype == dt.STR

Try / catch

try:
    pw.io.leann.write(table, "idx", table.text)
except ValueError as e:
    if "must be of type str" in str(e):
        table = table.with_columns(text=table.text.astype(str))
    else:
        raise

Prevention

When it happens

Trigger: Calling pw.io.leann.write(table, path, text_column=table.doc_id) where doc_id is INT/ANY/etc.; or listing a metadata column whose dtype is not dt.STR (e.g. an int id or a Json column).

Common situations: Passing a numeric id or timestamp column as metadata; columns parsed with schema autodetection that came out as int; columns that hold Optional[str] (dt.STR is still used, but a plain object column from apply() without dtype hints becomes ANY).

Related errors


AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15). Data as JSON: /api/errors/14b4e572d7cc9e15. Report an issue: GitHub.