clockworklabs/SpacetimeDB · warning · InvalidOperationException

Unknown Result variant.

Error message

Unknown Result variant.

What it means

Defensive default arm of Result<T,E>.UnwrapOrThrow() in the C# BSATN runtime. The switch already handles both sealed variants OkR and ErrR; the `_` arm only executes if `this` is neither, which cannot happen through the public API because OkR/ErrR are the only nested records and Ok/Err are the only constructors. Reaching it requires a third Result subtype, which is only possible via a user-added partial declaration of `partial record Result<T,E>` or reflection magic.

Source

Thrown at crates/bindings-csharp/BSATN.Runtime/Builtins.cs:662

            OkR(var v) => onOk(v),
            ErrR(var e) => onErr(e),
            _ => throw new InvalidOperationException("Unknown Result variant."),
        };

    public static Result<T, E> Ok(T value) => new OkR(value);

    public static Result<T, E> Err(E error) => new ErrR(error);

    public T UnwrapOrThrow()
    {
        return this switch
        {
            OkR(var v) => v,
            ErrR(var e) when e is not null => throw new Exception(e.ToString()),
            ErrR(_) => throw new InvalidOperationException(
                "Result failed without an error object."
            ),
            _ => throw new InvalidOperationException("Unknown Result variant."),
        };
    }

    public T UnwrapOr(T defaultValue) =>
        this switch
        {
            OkR(var v) => v,
            _ => defaultValue,
        };

    public T UnwrapOrElse(Func<E, T> f) =>
        this switch
        {
            OkR(var v) => v,
            ErrR(var e) => f(e),
            _ => throw new InvalidOperationException("Unknown Result variant."),
        };

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Search your codebase for extra `partial record Result<` declarations or subclasses of Result and remove them
  2. Use only Result.Ok()/Result.Err() and the implicit conversions to construct Results
  3. If it reproduces with stock SpacetimeDB packages, file a bindings bug with the stack trace
Defensive patterns

Strategy: type-guard

Type guard

static bool IsKnownVariant<T, E>(Result<T, E> r) =>
    r is Result<T, E>.OkR or Result<T, E>.ErrR;

Try / catch

try { var v = result.UnwrapOrThrow(); }
catch (InvalidOperationException ioe) when (ioe.Message == "Unknown Result variant.")
{
    // a third Result subtype exists (partial-declaration extension) — audit your codebase
}

Prevention

When it happens

Trigger: Declaring an additional `public sealed record MyVariant : Result<T,E>` via the partial record and calling UnwrapOrThrow() on it; a forked/modified BSATN.Runtime that adds a variant without updating the switch; theoretically a corrupted object state from unsafe code.

Common situations: Almost never seen in the wild; when it is, it follows a library upgrade where a local partial extension of Result conflicted with a new runtime version, or debug builds with patched/instrumented assemblies.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20). Data as JSON: /api/errors/5d716fbb50385d8e. Report an issue: GitHub.