cocoindex-io/cocoindex · error · ValueError
Unsupported record type: {self.record_type}
Error message
Unsupported record type: {self.record_type} What it means
RecordType.fields can extract field metadata only from dataclasses, NamedTuples, and Pydantic models — the types is_record_type recognizes. If a RecordType was constructed for some other type, iterating .fields falls through all branches and raises ValueError.
Source
Thrown at python/cocoindex/_internal/datatype.py:162
yield RecordFieldInfo(
name=name,
type_hint=type_hints.get(name, Any),
default_value=defaults.get(name, inspect.Parameter.empty),
description=None,
)
elif is_pydantic_model(self.record_type):
model_fields = getattr(self.record_type, "model_fields", {})
for name, field_info in model_fields.items():
yield RecordFieldInfo(
name=name,
type_hint=type_hints.get(name, Any),
default_value=field_info.default
if field_info.default is not ...
else inspect.Parameter.empty,
description=field_info.description,
)
else:
raise ValueError(f"Unsupported record type: {self.record_type}")
class UnionType(NamedTuple):
"""
Any union type, e.g. T1 | T2 | ..., etc.
"""
variant_types: list[Any]
class MappingType(NamedTuple):
"""
Any dict type, e.g. dict[T1, T2], Mapping[T1, T2], etc.
"""
key_type: Any
value_type: Any
View on GitHub (pinned to e84aa99b32)
Solutions
- Convert the type to a @dataclass, typing.NamedTuple, or pydantic.BaseModel
- Check is_record_type(t) before constructing RecordType in custom analysis code
- If using TypedDict, switch to a dataclass with equivalent fields
Example fix
// before
class Row(TypedDict):
id: int
// after
@dataclasses.dataclass
class Row:
id: int Defensive patterns
Strategy: type-guard
Validate before calling
from cocoindex._internal.datatype import is_record_type
if not is_record_type(Row):
raise TypeError(f"{Row} must be dataclass/NamedTuple/pydantic model") Type guard
def is_valid_record(t: type) -> bool:
return dataclasses.is_dataclass(t) or hasattr(t, "_fields") or (
PYDANTIC_AVAILABLE and issubclass(t, pydantic.BaseModel)) Try / catch
try:
fields = list(RecordType(record_type=Row).fields)
except ValueError as e:
logging.error("record type unsupported: %s", e)
Row = dataclasses.dataclass(Row) # or switch to a supported class Prevention
- Use @dataclass, typing.NamedTuple, or pydantic.BaseModel for all record schemas
- Avoid TypedDict and plain classes for indexed records
- Run schema analysis in unit tests so unsupported types surface early
When it happens
Trigger: Passing a plain class, TypedDict, attrs class (without recognition), or a NamedTuple-like object lacking _fields into a code path that wraps it in RecordType and iterates fields; or is_record_type and fields going out of sync (e.g. a type that passed the record check but whose specific kind isn't handled).
Common situations: Using TypedDict for schema rows (not supported); defining a custom struct class and expecting it to be treated as a record; a library upgrade changing the recognized record kinds.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- record_type must be a record type (dataclass, NamedTuple, Py
- Primary key column '{pk}' not found in columns: {list(self.c
- record_type must be a record type (dataclass, NamedTuple, Py
- VectorSchemaProvider is required for NumPy ndarray type.
- primary_key {primary_key!r} not found in columns ({sorted(co
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/1d01f88267e3eaeb.
Report an issue: GitHub.