{"record":{"id":"05852d7634e89530","repo":"cocoindex-io/cocoindex","slug":"from-table-must-be-specified-for-polymorphic-relat","errorCode":null,"errorMessage":"from_table must be specified for polymorphic relations (possible tables: {self._from_table_names})","messagePattern":"from_table must be specified for polymorphic relations \\(possible tables: (.+?)\\)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/surrealdb/_target.py","lineNumber":1206,"sourceCode":"        self._default_to_table = to_table_names[0] if len(to_table_names) == 1 else None\n\n    def declare_relation(\n        self: RelationTarget[RowT],\n        *,\n        from_id: Any,\n        to_id: Any,\n        record: RowT | None = None,\n        from_table: TableTarget[Any] | None = None,\n        to_table: TableTarget[Any] | None = None,\n    ) -> None:\n        \"\"\"Declare a relation record.\"\"\"\n        # Resolve from_table_name\n        if from_table is not None:\n            from_table_name = from_table.table_name\n        elif self._default_from_table is not None:\n            from_table_name = self._default_from_table\n        else:\n            raise ValueError(\n                \"from_table must be specified for polymorphic relations \"\n                f\"(possible tables: {self._from_table_names})\"\n            )\n\n        # Resolve to_table_name\n        if to_table is not None:\n            to_table_name = to_table.table_name\n        elif self._default_to_table is not None:\n            to_table_name = self._default_to_table\n        else:\n            raise ValueError(\n                \"to_table must be specified for polymorphic relations \"\n                f\"(possible tables: {self._to_table_names})\"\n            )\n\n        # Build the value dict from the record (exclude 'id' — it's the key, not content)\n        if record is not None:\n            if self._table_schema is not None:","sourceCodeStart":1188,"sourceCodeEnd":1224,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/surrealdb/_target.py#L1188-L1224","documentation":"When declaring a relation on a polymorphic (multi-table) relation target, the source table cannot be inferred: there is no single default from-table, so `declare_relation` raises ValueError listing the candidate tables. The caller must name which table the relation originates from.","triggerScenarios":"Calling `declare_relation(...)` without `from_table=...` on a relation target whose `_default_from_table` is None (multiple from-tables were declared).","commonSituations":"Graph-style schemas where edges can start from several node tables (User, Post, Comment); forgetting that polymorphic relations require explicit endpoints.","solutions":["Pass `from_table=<TableTarget>` for one of the tables listed in the error message's `(possible tables: ...)`.","If all relations truly come from one table, declare the relation target with that single from-table so a default exists.","Check the possible-tables list in the message and use the exact table object/name."],"exampleFix":"// before\nawait rel_target.declare_relation(record=edge, to_table=post_table)\n// after\nawait rel_target.declare_relation(record=edge, from_table=user_table, to_table=post_table)","handlingStrategy":"validation","validationCode":"if from_table is None and rel_target.default_from_table is None:\n    raise ValueError(\"declare_relation requires from_table for polymorphic relation targets\")","typeGuard":"def can_omit_from_table(rel_target) -> bool:\n    return getattr(rel_target, \"_default_from_table\", None) is not None","tryCatchPattern":"try:\n    await rel_target.declare_relation(record=rec, to_table=dst)\nexcept ValueError as e:\n    if \"from_table must be specified\" in str(e):\n        await rel_target.declare_relation(record=rec, from_table=src, to_table=dst)\n    else:\n        raise","preventionTips":["Always pass explicit from_table/to_table when the relation target has multiple node tables.","Read the possible-tables list from the error message to pick a valid table.","Keep relation declarations next to table declarations so endpoints are obvious."],"tags":["python","graph","surrealdb","config"],"backgroundTag":"missing-required-argument","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"}