cocoindex-io/cocoindex · error · ValueError

ZvecFtsType on column {name!r} requires a str field, got {ty

Error message

ZvecFtsType on column {name!r} requires a str field, got {type_info.base_type!r}.

What it means

Type-compatibility guard for full-text columns in _resolve_column. ZvecFtsType indexes textual content, so it is only meaningful on a str field; applying it to any other base type (int, list, ndarray, etc.) would create a column the engine cannot index for full-text search. Raised during schema construction when the annotated field's resolved type is not str. Either change the field to str or remove the ZvecFtsType annotation.

Source

Thrown at python/cocoindex/connectors/zvec/_target.py:405

            data_type=_zvec.DataType.SPARSE_VECTOR_FP32,
            nullable=type_info.nullable,
            metric=vector_def.metric,
        )

    if type_info.base_type is np.ndarray:
        raise ValueError(
            f"Vector column {name!r} requires a VectorSchema (provide it via an "
            "Annotated NDArray or column_overrides)."
        )

    # Full-text field: str marked with ZvecFtsType.
    if fts_type is not None:
        if zvec_type is not None:
            raise ValueError(
                f"Column {name!r} cannot combine ZvecFtsType with ZvecType."
            )
        if type_info.base_type is not str:
            raise ValueError(
                f"ZvecFtsType on column {name!r} requires a str field, got "
                f"{type_info.base_type!r}."
            )
        return _Column(
            name=name,
            kind="fts",
            data_type=_zvec.DataType.STRING,
            nullable=type_info.nullable,
            tokenizer_name=fts_type.tokenizer_name,
            filters=fts_type.filters,
            extra_params=fts_type.extra_params,
        )

    # Scalar field.
    if zvec_type is not None:
        return _Column(
            name=name,
            kind="scalar",

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Change the field type to str
  2. Remove ZvecFtsType if the field should not be searched
  3. Cast the value to str in the producing function before indexing

Example fix

// before
count: Annotated[int, ZvecFtsType()]
// after
count: int
Defensive patterns

Strategy: validation

Validate before calling

assert isinstance(getattr(Row, field_name), property) or get_type_hints(Row)[field_name] is str, "ZvecFtsType requires str"

Type guard

def is_fts_candidate(hint: object) -> bool:
    base = get_args(hint)[0] if get_origin(hint) is Annotated else hint
    return base is str

Try / catch

try:
    schema = ZvecCollection.from_class(Row)
except ValueError as e:
    if "ZvecFtsType" in str(e) and "str field" in str(e):
        # remove ZvecFtsType or change the field to str
        ...
    else:
        raise

Prevention

When it happens

Trigger: Applying ZvecFtsType to an int, bytes, list, or other non-str field in a from_class row class.

Common situations: Marking a numeric or binary field for full-text search by mistake; schema drift where a field changed type after FTS annotation was added.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/940e25248a9c8c97. Report an issue: GitHub.