{"record":{"id":"8531f2dbbbb5138e","repo":"cocoindex-io/cocoindex","slug":"record-type-must-be-a-record-type-dataclass-name-8531f2","errorCode":null,"errorMessage":"record_type must be a record type (dataclass, NamedTuple, Pydantic model), got {type(record_type)}","messagePattern":"record_type must be a record type \\(dataclass, NamedTuple, Pydantic model\\), got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/sqlite/_target.py","lineNumber":358,"sourceCode":"        record_type: type[RowT],\n        primary_key: list[str],\n        *,\n        column_overrides: dict[str, SqliteType | res_schema.VectorSchemaProvider]\n        | None = None,\n    ) -> \"TableSchema[RowT]\":\n        \"\"\"\n        Create a TableSchema from a record type (dataclass, NamedTuple, or Pydantic model).\n\n        Python types are automatically mapped to SQLite types.\n\n        Args:\n            record_type: A record type (dataclass, NamedTuple, or Pydantic model).\n            primary_key: List of column names that form the primary key.\n            column_overrides: Optional dict mapping column names to SqliteType or\n                              VectorSchemaProvider to override the default type mapping.\n        \"\"\"\n        if not is_record_type(record_type):\n            raise TypeError(\n                f\"record_type must be a record type (dataclass, NamedTuple, Pydantic model), \"\n                f\"got {type(record_type)}\"\n            )\n        columns = await cls._columns_from_record_type(record_type, column_overrides)\n        return cls(columns, primary_key, row_type=record_type)\n\n    @staticmethod\n    async def _columns_from_record_type(\n        record_type: type,\n        column_overrides: dict[str, SqliteType | res_schema.VectorSchemaProvider]\n        | None,\n    ) -> dict[str, ColumnDef]:\n        \"\"\"Convert a record type to a dict of column name -> ColumnDef.\"\"\"\n        record_info = RecordType(record_type)\n        columns: dict[str, ColumnDef] = {}\n\n        for rec_field in record_info.fields:\n            override = (","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/sqlite/_target.py#L340-L376","documentation":"The `table_target`/`from_class` factory for the SQLite connector requires `record_type` to be a supported record type (dataclass, NamedTuple, or Pydantic model). The library validates this with `is_record_type()` and raises `TypeError` when any other value (e.g. a plain class, dict, or instance) is passed, because it relies on record introspection to derive column names and types.","triggerScenarios":"Calling `SqliteTarget.from_class(record_type=...)` (or `table_target(...)` with a record-based schema) with a value that is not a dataclass, NamedTuple, or Pydantic model — e.g. a plain `class`, a `dict`, a TypedDict, or an *instance* of a dataclass instead of the class itself.","commonSituations":"Developers pass a TypedDict (looks record-like but is not supported), pass an instantiated row object instead of the type, or use a plain class without the `@dataclass` decorator. Also common when a refactor changes a dataclass into a regular class or attrs model.","solutions":["Annotate the class with `@dataclass` (or make it a NamedTuple / subclass a Pydantic BaseModel) and pass the class itself, not an instance","If you cannot change the type, build the table schema with explicit `SqliteColumn` definitions instead of deriving them from a record type","Check that the import points at the class, not a module or instance variable"],"exampleFix":"// before\nrow = MyRow(id=1, text=\"hi\")\ntarget = sqlite.table_target(\"docs\", record_type=row, primary_key=[\"id\"])\n// after\n@dataclass\nclass MyRow:\n    id: int\n    text: str\n\ntarget = sqlite.table_target(\"docs\", record_type=MyRow, primary_key=[\"id\"])","handlingStrategy":"type-guard","validationCode":"import dataclasses\nfrom cocoindex.connectors.sqlite import _target  # or use the public helper\nassert dataclasses.is_dataclass(MyRow) or issubclass(MyRow, tuple) or issubclass(MyRow, BaseModel)","typeGuard":"def is_record_type_ok(rt: object) -> bool:\n    import dataclasses\n    from pydantic import BaseModel\n    return (\n        isinstance(rt, type)\n        and (dataclasses.is_dataclass(rt) or issubclass(rt, tuple) or issubclass(rt, BaseModel))\n    )","tryCatchPattern":"try:\n    target = sqlite.table_target(\"docs\", record_type=MyRow, primary_key=[\"id\"])\nexcept TypeError as e:\n    if \"record_type must be a record type\" in str(e):\n        raise ValueError(\"Pass the record class (dataclass/NamedTuple/Pydantic), not an instance\") from e\n    raise","preventionTips":["Always pass the class, never an instance, as record_type","Prefer @dataclass for row types; avoid TypedDict, which is not supported","Check the primary_key names exist as fields on the record type"],"tags":["python","type-mismatch","sqlite","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b","analyzedAt":"2026-09-08T15:59:19.997Z","contentChangedAt":"2026-09-08T15:59:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}