{"record":{"id":"7de315f3f0e6e043","repo":"cocoindex-io/cocoindex","slug":"record-type-must-be-a-record-type-dataclass-name-7de315","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/postgres/_target.py","lineNumber":385,"sourceCode":"        primary_key: list[str],\n        *,\n        column_overrides: dict[str, PgType | 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 PostgreSQL types based on asyncpg's\n        type conversion.\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 PgType 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, PgType | res_schema.VectorSchemaProvider] | 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 field in record_info.fields:\n            type_info = analyze_type_info(field.type_hint)\n","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/postgres/_target.py#L367-L403","documentation":"TableTarget.from_class derives column definitions by introspecting a record type, which must be a dataclass, NamedTuple, or Pydantic model. Anything else cannot be introspected, so a TypeError is raised naming the offending type.","triggerScenarios":"Calling `await PgTableTarget.from_class(dict)` or passing a TypedDict, plain class, or an instance rather than a supported record class.","commonSituations":"Passing a TypedDict for convenience; forgetting the @dataclass decorator; passing an instance (MyRow(...)) instead of the class.","solutions":["Convert the type to a @dataclass, NamedTuple, or Pydantic BaseModel.","Pass the class, not an instance.","For non-record schemas, build the columns dict manually and call the constructor directly."],"exampleFix":"// before\ntarget = await PgTableTarget.from_class(dict, primary_key=[\"id\"])\n// after\n@dataclass\nclass UserRow:\n    id: int\n    name: str\ntarget = await PgTableTarget.from_class(UserRow, primary_key=[\"id\"])","handlingStrategy":"type-guard","validationCode":"import dataclasses\nassert dataclasses.is_dataclass(Row) or issubclass(Row, tuple) or hasattr(Row, \"model_fields\")","typeGuard":"def is_record_class(t: object) -> bool:\n    import dataclasses\n    return (\n        isinstance(t, type)\n        and (dataclasses.is_dataclass(t)\n             or issubclass(t, tuple) and hasattr(t, \"_fields\")\n             or hasattr(t, \"model_fields\"))\n    )","tryCatchPattern":"try:\n    target = await PgTableTarget.from_class(Row, primary_key=[\"id\"])\nexcept TypeError as e:\n    if \"must be a record type\" in str(e):\n        raise ValueError(\"Pass a @dataclass/NamedTuple/BaseModel class, not an instance or dict\") from e","preventionTips":["Define table row schemas as dataclasses and pass the class, never an instance or dict.","Avoid TypedDict here; it is not accepted as a record type.","Use typing to annotate from_class so type checkers catch wrong arguments early."],"tags":["python","type-error","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-17T15:17:12.973Z"}