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
- Search your codebase for extra `partial record Result<` declarations or subclasses of Result and remove them
- Use only Result.Ok()/Result.Err() and the implicit conversions to construct Results
- 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
- Do not extend Result<T,E> with partial declarations or subclasses
- Treat this exception as a library-contract violation and report it upstream with the stack trace
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
- Result failed without an error object.
- Operation is not valid due to the current state of the objec
- Unsupported type {type}
- Invalid tag value, this state should be unreachable.
- Unsupported special type {type} ({type.SpecialType})
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/5d716fbb50385d8e.
Report an issue: GitHub.