clockworklabs/SpacetimeDB · error · anyhow::Error

Unsupported .NET SDK version

Error message

Unsupported .NET SDK version: {major}. SpacetimeDB requires .NET SDK 8.0 or 10.0.

What it means

Internal helper dotnet_global_json(major) renders the global.json SDK-pinning template used in error messages and project setup; only .NET SDK majors 8 and 10 have templates, anything else bails here. In the current code it is only called with the build path's resolved SDK (always 8 or 10), so reaching this error means an internal invariant broke or a new call site passed an unvalidated major.

Solutions

  1. As a user: use .NET SDK 8 or 10, the only supported majors; re-run with --dotnet-version 8 or --dotnet-version 10 if you passed a version.
  2. As a CLI developer: validate the major at the clap/arg-parsing boundary (accept only 8 or 10) so this remains an unreachable invariant.
  3. If hit unexpectedly, report it as a CLI bug with the exact command line.
Defensive patterns

Strategy: validation

Validate before calling

# Accept only supported majors before invoking the toolchain
case "$DOTNET_VERSION" in 8|10) ;; *) echo "unsupported --dotnet-version (use 8 or 10)" >&2; exit 2 ;; esac
spacetime build --dotnet-version "$DOTNET_VERSION"

Prevention

When it happens

Trigger: A code path passing an SDK major other than 8/10 into dotnet_global_json -- e.g. a future `spacetime init --dotnet-version 9` flowing through unchecked, or a new CsharpBuildPath variant added without a template. Not reachable through normal CLI usage today.

Common situations: CLI development after adding a build path or version flag; --dotnet-version values not validated at the arg-parsing boundary before reaching the build tasks.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@9e0d92412f (2026-08-20). Data as JSON: /api/errors/d397195a20e4ff68. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/tasks/csharp.rs:18

use anyhow::Context;
use itertools::Itertools;
use std::collections::HashSet;
use std::ffi::OsString;
use std::fs;
use std::path::{Path, PathBuf};

use crate::common_args::{nativeaot_unsupported_on_host, NATIVEAOT_UNSUPPORTED_MESSAGE};

pub(crate) fn parse_major_version(version: &str) -> Option<u8> {
    version.split('.').next()?.parse::<u8>().ok()
}

fn dotnet_global_json(major: u8) -> anyhow::Result<String> {
    match major {
        8 => Ok(r#"{"sdk":{"version":"8.0.100","rollForward":"latestFeature"}}"#.to_string()),
        10 => Ok(r#"{"sdk":{"version":"10.0.100","rollForward":"latestMinor"}}"#.to_string()),
        _ => anyhow::bail!("Unsupported .NET SDK version: {major}. SpacetimeDB requires .NET SDK 8.0 or 10.0."),
    }
}

#[derive(Debug)]
struct CsprojTargetFrameworks {
    path: PathBuf,
    majors: Vec<u8>,
}

impl CsprojTargetFrameworks {
    fn single_major(&self) -> Option<u8> {
        (self.majors.len() == 1).then_some(self.majors[0])
    }
}

/// Read the target framework major versions directly from the project's `.csproj` file.
/// Returns `net8.0`, `net10.0`, etc. from both `<TargetFramework>` and `<TargetFrameworks>`.
/// Multi-target projects do not imply a single selected SDK version; callers should use a

View on GitHub (pinned to 9e0d92412f)