{"record":{"id":"d0a69ed890cda640","repo":"clockworklabs/SpacetimeDB","slug":"type-s-contains-a-circular-reference-to-itsel","errorCode":null,"errorMessage":"  Type '%s' contains a circular reference to itself\n","messagePattern":"  Type '(.+?)' contains a circular reference to itself\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bindings-cpp/src/internal/Module.cpp","lineNumber":233,"sourceCode":"        // Create the error type name that indicates the circular reference\n        std::string error_type_name = \"ERROR_CIRCULAR_REFERENCE_\" + g_circular_ref_type_name;\n        \n        // Add a single named type export that points to a non-existent typespace index\n        // This will cause SpacetimeDB to error when it tries to resolve the type\n        RawTypeDefV10 error_type;\n        error_type.source_name.scope = {};\n        error_type.source_name.source_name = error_type_name;\n        error_type.ty = 999999; // Invalid typespace index - will cause an error\n        error_type.custom_ordering = false;\n        \n        getV10Builder().GetTypeDefs().push_back(error_type);\n        \n        // Don't add anything to the typespace - this ensures the reference is invalid\n        // The server will fail with an error message that includes our error type name\n        \n        // Also log to stderr for debugging\n        fprintf(stderr, \"\\n[CIRCULAR REFERENCE ERROR] Module cleared and replaced with error type: %s\\n\", error_type_name.c_str());\n        fprintf(stderr, \"  Type '%s' contains a circular reference to itself\\n\", g_circular_ref_type_name.c_str());\n        fflush(stderr);\n        return; // Exit early, don't check other errors\n    }\n    \n    // Check if multiple primary key error occurred during constraint registration\n    if (g_multiple_primary_key_error) {\n        // Multiple primary key error detected - create a special error module\n        \n        // Clear the module state to start fresh.\n        getV10Builder().Clear();\n        \n        // Create the error type name\n        std::string error_type_name = \"ERROR_MULTIPLE_PRIMARY_KEYS_\" + g_multiple_primary_key_table_name;\n        \n        // Add a single named type export that points to a non-existent typespace index\n        // This will cause SpacetimeDB to error when it tries to resolve the type\n        RawTypeDefV10 error_type;\n        error_type.source_name.scope = {};","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/bindings-cpp/src/internal/Module.cpp#L215-L251","documentation":"Second line of the circular-reference diagnostic, printed right after '[CIRCULAR REFERENCE ERROR] Module cleared and replaced with error type: ...'. It names the exact offending type (g_circular_ref_type_name) that re-entered its own type registration. It is informational detail for error 664 - the fix targets the named type, not this line.","triggerScenarios":"Always emitted together with the 664 banner whenever g_circular_ref_error is set during type registration; the named type is the one whose registration was re-entered (directly or via a nested field type).","commonSituations":"Self-referential table column types (tree/graph models); mutually recursive structs both used as table columns.","solutions":["Open the type named in this line and remove the self-reference (replace nested recursive members with row ids)","If the named type looks non-recursive, check its field types transitively - the cycle may re-enter through a nested container","Republish after restructuring; the ERROR_CIRCULAR_REFERENCE_* error type disappears once the cycle is gone"],"exampleFix":"// before\nstruct Tree { std::vector<Tree> branches; };\n\n// after\nstruct Tree { std::vector<uint64_t> branch_ids; };","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the type name from this line to jump straight to the offending definition","Check the named type's fields transitively (containers of containers) for the cycle","Prefer id-reference patterns for any parent/child linkage between rows"],"tags":["spacetimedb","cpp","types","circular-reference","diagnostics"],"backgroundTag":"recursive-type-definition","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}