clockworklabs/SpacetimeDB · error

ERROR: Skipping view registration '%s' because circular refe

Error message

ERROR: Skipping view registration '%s' because circular reference error is set

What it means

RegisterView refuses to register a view because g_circular_ref_error is set — the module's type registration already detected a circular type reference. Views take a ViewContext or AnonymousViewContext first parameter and return rows of some type; when that (or any other) type closed a cycle, the global flag was set and this registration is skipped so the broken module gains no further entries. preinit_99 later fails the whole module, so this is a cascade of the type-cycle error.

Source

Thrown at crates/bindings-cpp/include/spacetimedb/internal/v10_builder.h:454

        RawReducerDefV10 reducer_def{
            reducer_name,
            ProductType{},
            FunctionVisibility::Private,
            MakeUnitAlgebraicType(),
            MakeStringAlgebraicType(),
        };
        UpsertReducer(reducer_def);
        UpsertLifecycleReducer(RawLifeCycleReducerDefV10{lifecycle, reducer_name});
    }

    template<typename Func>
    void RegisterView(const std::string& view_name,
                      Func func,
                      bool is_public,
                      const std::vector<std::string>& param_names = {}) {
        if (g_circular_ref_error) {
            std::fprintf(stderr, "ERROR: Skipping view registration '%s' because circular reference error is set\n",
                        view_name.c_str());
            return;
        }
        (void)param_names;
        using traits = function_traits<Func>;
        using ContextType = std::remove_cv_t<std::remove_reference_t<typename traits::template arg_t<0>>>;
        using ReturnType = typename traits::result_type;
        static_assert(traits::arity > 0, "View must have at least one parameter (ViewContext or AnonymousViewContext)");
        static_assert(std::is_same_v<ContextType, ViewContext> || std::is_same_v<ContextType, AnonymousViewContext>,
            "First parameter of view must be ViewContext or AnonymousViewContext");

        if constexpr (std::is_same_v<ContextType, ViewContext>) {
            std::function<std::vector<uint8_t>(ViewContext&, BytesSource)> handler =
                [func](ViewContext& ctx, BytesSource args_source) -> std::vector<uint8_t> {
                    (void)args_source;
                    auto result = func(ctx);
                    IterBuf buf = IterBuf::take();
                    bsatn::Writer writer(buf.get());

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Fix the '[CIRCULAR REFERENCE DETECTED]' type named earlier in stderr (use ID members instead of embedded values)
  2. Audit the view's row type and its nested members for self-reference through Vec/Option/struct members
  3. Rebuild; confirm the view appears in the published module
  4. Remember the guard fires for the whole module — one cycle suppresses every view, reducer, and index registration after it

Example fix

// before — view over recursive row type is skipped
struct Item { std::vector<Item> subitems; };
// after
struct Item { std::vector<uint64_t> subitem_ids; };
Defensive patterns

Strategy: validation

Validate before calling

#include <spacetimedb/internal/module_type_registration.h>
TEST(Module, ViewsRegistered) {
    EXPECT_FALSE(SpacetimeDB::Internal::g_circular_ref_error);
}

Prevention

When it happens

Trigger: The ST_VIEW macro instantiates a static registration calling RegisterView('<view>', fn) whose result/parameter types are, or depend on, a self- or mutually-referential type. Type building runs before view registration during static init, sets the flag, and the view is dropped with this message.

Common situations: Adding a view over a table whose row type was just made recursive; combining views with hierarchy-style schemas that embed children by value; bindings upgrades that moved view registration after type building, surfacing pre-existing cycles.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/00866fd6aa6e170a. Report an issue: GitHub.