clockworklabs/SpacetimeDB · error · anyhow::Error

dotnet not found in PATH. Please install .NET SDK 8.0 or…

Error message

dotnet not found in PATH. Please install .NET SDK 8.0 or 10.0.

What it means

When resolving the SDK for a C# module, the CLI runs `dotnet --version` if a global.json exists in the project directory or the current working directory. If the OS reports ErrorKind::NotFound, the dotnet executable is missing from PATH and the CLI bails with an install hint for .NET SDK 8.0 or 10.0. Without a global.json the probe is skipped entirely and the SDK is chosen from the csproj or defaults.

Solutions

  1. Install the .NET SDK 8.0 or 10.0 (e.g. `winget install Microsoft.DotNet.SDK.8`, `apt install dotnet-sdk-8.0`, or the dotnet-install script).
  2. If already installed, fix PATH so `command -v dotnet` succeeds in the same shell/CI step that runs spacetime.
  3. In CI, add a .NET SDK setup step before the spacetime build step.

Example fix

# before: CI step fails with 'dotnet not found in PATH'
- run: spacetime build
# after
- uses: actions/setup-dotnet@v4
  with: { dotnet-version: '8.0.x' }
- run: spacetime build
Defensive patterns

Strategy: validation

Validate before calling

# Fail fast with a clear message before building
command -v dotnet >/dev/null 2>&1 || { echo "dotnet not on PATH" >&2; exit 1; }
dotnet --version >/dev/null 2>&1 || exit 1
spacetime build

Prevention

When it happens

Trigger: `spacetime build` / `spacetime publish` on a C# project whose directory or cwd contains a global.json, on a machine where the dotnet executable is not installed or not on the PATH inherited by the spacetime process.

Common situations: Fresh CI images without the .NET SDK; dotnet installed via snap/homebrew but PATH not propagated to the shell or service running spacetime; Windows with only the .NET runtime (not the SDK) installed.

Related errors


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

Appendix: source

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

        };
    }

    let native_aot_flag = native_aot;

    let project_global_json = find_global_json(project_path);
    let cwd = std::env::current_dir()?;
    let cwd_global_json = find_global_json(&cwd);
    let dotnet_version_result = if project_global_json.is_some() {
        Some(dotnet!("--version").read())
    } else if cwd_global_json.is_some() {
        Some(duct::cmd!("dotnet", "--version").read())
    } else {
        None
    };
    let dotnet_version_str = match dotnet_version_result {
        Some(Ok(v)) => Some(v),
        Some(Err(error)) if error.kind() == std::io::ErrorKind::NotFound => {
            anyhow::bail!("dotnet not found in PATH. Please install .NET SDK 8.0 or 10.0.")
        }
        Some(Err(error)) => anyhow::bail!("{error}"),
        None => None,
    };

    // Resolution order:
    //   1. --dotnet-version CLI flag (explicit user override)
    //   2. global.json-selected SDK, if one applies to the project or current directory
    //   3. Single <TargetFramework> in the project's .csproj
    //   4. .NET 10 default for missing or multi-target project context
    let csproj_tfms = read_tfms_from_csproj(project_path);
    let dotnet_major = dotnet_version_override
        .or_else(|| dotnet_version_str.as_deref().and_then(parse_major_version))
        .or_else(|| csproj_tfms.as_ref().and_then(CsprojTargetFrameworks::single_major))
        .or(Some(10));

    // Determine the build path based on SDK version and --native-aot flag.
    let build_path = match (dotnet_major, native_aot_flag) {

View on GitHub (pinned to 9e0d92412f)