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
- Cast the column to string before writing: table.col.astype(str) or table.select(txt=pw.this.col.astype(pw.ColumnSchema(dtype=pw.STR)))
- Ensure the read schema declares the column as str (class X(Schema): col: str)
- 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
- Declare str types explicitly in the read schema for text columns
- Cast numeric metadata columns with .astype(str) before the write
- Check col._column.dtype == pw.dt.STR in helper code wiring dynamic columns
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
- Pathway does not support using binary operator {expression._
- Incompatible types in for a binary operator. The types are:
- Pathway does not support using reducer {self} on column of t
- Pathway does not support using reducer {self.name} on column
- The topic name column must have a string type, however {topi
AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15).
Data as JSON: /api/errors/14b4e572d7cc9e15.
Report an issue: GitHub.