cocoindex-io/cocoindex · error · TypeError
record_type must be a record type (dataclass, NamedTuple, Py
Error message
record_type must be a record type (dataclass, NamedTuple, Pydantic model), got {type(record_type)} What it means
from_class derives the target's columns from the record type's fields, which requires a dataclass, NamedTuple, or Pydantic model. If record_type is any other type (str, dict, plain class, None), is_record_type fails and a TypeError is raised naming the actual type received.
Source
Thrown at python/cocoindex/connectors/bigquery/_target.py:148
@classmethod
async def from_class(
cls,
record_type: type[RowT],
primary_key: list[str],
*,
column_overrides: dict[str, BigQueryType] | None = None,
) -> "TableSchema[RowT]":
"""
Create a TableSchema from a record type.
Args:
record_type: A dataclass, NamedTuple, or Pydantic model.
primary_key: List of column names that form the primary key.
column_overrides: Optional per-column BigQueryType overrides.
"""
if not is_record_type(record_type):
raise TypeError(
f"record_type must be a record type (dataclass, NamedTuple, Pydantic model), "
f"got {type(record_type)}"
)
columns = await cls._columns_from_record_type(record_type, column_overrides)
return cls(columns, primary_key, row_type=record_type)
@staticmethod
async def _columns_from_record_type(
record_type: type,
column_overrides: dict[str, BigQueryType] | None,
) -> dict[str, ColumnDef]:
"""Convert a record type to a dict of column name to ColumnDef."""
record_info = RecordType(record_type)
columns: dict[str, ColumnDef] = {}
for field in record_info.fields:
override = column_overrides.get(field.name) if column_overrides else None
type_info = analyze_type_info(field.type_hint)View on GitHub (pinned to e84aa99b32)
Solutions
- Pass an actual dataclass, NamedTuple, or Pydantic model class (not a string, dict, or instance).
- Add the @dataclass decorator if you intended a dataclass but forgot it.
- Convert a TypedDict to NamedTuple or dataclass, or use Pydantic BaseModel.
- Ensure you pass the class object itself, e.g. Row, not Row() or 'Row'.
Example fix
// before
target = table_target(client, "proj.ds.tbl", {"id": "INT64"}, primary_key=["id"])
// after
@dataclass
class Row:
id: int
name: str
target = table_target(client, "proj.ds.tbl", Row, primary_key=["id"]) Defensive patterns
Strategy: type-guard
Validate before calling
import dataclasses assert dataclasses.is_dataclass(Row), "record_type must be a dataclass/NamedTuple/Pydantic model"
Type guard
def is_record_type(t: object) -> bool:
import dataclasses
if dataclasses.is_dataclass(t):
return True
if isinstance(t, type) and issubclass(t, tuple):
return hasattr(t, "_fields")
try:
from pydantic import BaseModel
return isinstance(t, type) and issubclass(t, BaseModel)
except ImportError:
return False Try / catch
try:
target = table_target(client, table, record_type, primary_key=pk)
except TypeError as e:
logger.error("bad record_type: %s", e)
raise Prevention
- Pass the class object, never its name or an instance.
- Always decorate intended dataclasses with @dataclass.
- Prefer NamedTuple/dataclass over TypedDict for table row types.
When it happens
Trigger: Calling table_target(..., record_type='MyRow') passing the class name as a string; passing a dict of column specs instead of a typed record; passing a plain (non-dataclass) class or a TypedDict.
Common situations: Confusing TypedDict with NamedTuple; forgetting the @dataclass decorator; passing an instance instead of the class; stringly-typed configuration of record types.
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
- record_type must be a record type (dataclass, NamedTuple, Py
- record_type must be a record type (dataclass, NamedTuple, Py
- record_type must be a record type (dataclass, NamedTuple, Py
- Unsupported record type: {self.record_type}
- timeout() requires a datetime.timedelta
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/652611378069abfe.
Report an issue: GitHub.