clockworklabs/SpacetimeDB · error

never types are not yet supported in C# output

Error message

never types are not yet supported in C# output

What it means

When generating C# bindings, the codegen must produce a default-value expression for every algebraic type (crates/codegen/src/csharp.rs:1383). The match has arms for strings, primitives, Result, and struct-like types, but AlgebraicTypeUse::Never hits unimplemented!() because an uninhabited type has no C# default. This is a codegen panic, not a graceful error.

Source

Thrown at crates/codegen/src/csharp.rs:1383

            AlgebraicTypeDef::Product(_) => Some("new()"),
        },
        // See Sum(_) handling above.
        AlgebraicTypeUse::ScheduleAt => Some("null!"),
        AlgebraicTypeUse::Array(_) => Some("new()"),
        // Strings must have explicit default value of "".
        AlgebraicTypeUse::String => Some(r#""""#),
        // Primitives are initialized to zero automatically.
        AlgebraicTypeUse::Primitive(_) => None,
        // Result<,> must be explicitly initialized.
        AlgebraicTypeUse::Result { .. } => Some("default!"),
        // these are structs, they are initialized to zero-filled automatically
        AlgebraicTypeUse::Unit
        | AlgebraicTypeUse::Identity
        | AlgebraicTypeUse::ConnectionId
        | AlgebraicTypeUse::Timestamp
        | AlgebraicTypeUse::TimeDuration
        | AlgebraicTypeUse::Uuid => None,
        AlgebraicTypeUse::Never => unimplemented!("never types are not yet supported in C# output"),
    }
}

struct CsharpAutogen {
    output: CodeIndenter<String>,
}

impl Deref for CsharpAutogen {
    type Target = CodeIndenter<String>;

    fn deref(&self) -> &Self::Target {
        &self.output
    }
}

impl std::ops::DerefMut for CsharpAutogen {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.output

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Remove the Never/empty-enum type from tables, reducer args/returns, and exported type definitions
  2. Replace it with a habitable placeholder (a unit struct or a bool/uint8 tag) if you need the slot
  3. Update the spacetimedb CLI and SDK to matching recent versions in case Never support has landed
  4. As a stopgap, generate bindings for a schema variant that excludes the Never-bearing type

Example fix

// before (Rust module)
#[spacetimedb::table]
pub struct Job { pub status: Status, pub err: Never }
enum Never {}

// after
#[spacetimedb::table]
pub struct Job { pub status: Status, pub err: Option<String> }
Defensive patterns

Strategy: validation

Validate before calling

# In module CI, fail early if the schema contains uninhabited types:
# (run before spacetime generate --lang csharp)
cargo build && cargo test schema_smoke
# schema_smoke: assert every #[table] / reducer-reachable type has at least one variant/value
# e.g. a test that reflectively publishes and asserts no Never in the generated ABI

Prevention

When it happens

Trigger: Running spacetime generate --lang csharp (or publishing a module whose schema is also consumed by C# clients) when the module ABI contains a Never type — e.g. an enum with no variants or a Rust '!' that leaked into a table column, reducer signature, or type alias.

Common situations: Declaring 'enum Void {}' as a placeholder column/payload type; SDK/toolchain version skew where the module emits a type shape the installed CLI's codegen cannot lower; experimenting with empty result types.

Related errors


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