{"record":{"id":"797e31df366ba43e","repo":"cocoindex-io/cocoindex","slug":"record-type-must-be-a-record-type-dataclass-name-797e31","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":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/lancedb/_target.py","lineNumber":277,"sourceCode":"        record_type: type[RowT],\n        primary_key: list[str],\n        *,\n        column_specs: dict[str, LanceType | 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 PyArrow 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_specs: Optional dict mapping column names to LanceType 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_specs)\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_specs: dict[str, LanceType | 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            spec = column_specs.get(field.name) if column_specs else None\n            type_info = analyze_type_info(field.type_hint)","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/lancedb/_target.py#L259-L295","documentation":"from_class builds the table schema from a record type, which must be a dataclass, NamedTuple, or Pydantic model (checked via is_record_type). Anything else (dict, plain class, typing construct, None) cannot be introspected into columns, so a TypeError is raised with the actual type.","triggerScenarios":"Calling `LanceDbTarget.from_class(record_type, ...)` with a non-record value: a plain class not decorated with @dataclass, a dict of fields, a typing construct, or accidentally passing an instance instead of the class.","commonSituations":"Forgetting the @dataclass decorator; passing the record instance rather than its type; migrating from another connector whose API accepted dicts.","solutions":["Pass a dataclass, NamedTuple, or Pydantic model class: decorate your class with @dataclass if needed.","Ensure you pass the type itself, not an instance.","Verify with `is_record_type(MyRecord)` before calling from_class."],"exampleFix":"// before\nawait target.from_class({\"id\": int, \"vec\": ...}, primary_key=[\"id\"])\n// after\n@dataclass\nclass MyRecord:\n    id: str\n    vec: np.ndarray\nawait target.from_class(MyRecord, primary_key=[\"id\"], column_specs={\"vec\": VectorSchemaProvider(size=768)})","handlingStrategy":"type-guard","validationCode":"from cocoindex.connectors.lancedb._target import is_record_type\nif not is_record_type(MyRecord):\n    raise TypeError(\"from_class needs a dataclass/NamedTuple/Pydantic model class\")","typeGuard":"def is_record(obj: object) -> bool:\n    import dataclasses\n    return isinstance(obj, type) and (\n        dataclasses.is_dataclass(obj)\n        or (issubclass(obj, tuple) and hasattr(obj, \"_fields\"))\n        or hasattr(obj, \"model_fields\")\n    )","tryCatchPattern":"try:\n    target = await LanceDbTarget.from_class(record_type, primary_key=[\"id\"])\nexcept TypeError as e:\n    if \"record_type must be a record type\" in str(e):\n        ...  # pass the class, decorated appropriately\n    raise","preventionTips":["Decorate schema classes with @dataclass (or use NamedTuple/Pydantic).","Pass the class itself, never an instance.","Centralize record type definitions and reuse them."],"tags":["python","lancedb","type-error","record-type"],"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"}