clockworklabs/SpacetimeDB · error · anyhow::Error

Could not auto-detect client language from '{}'. If this is

Error message

Could not auto-detect client language from '{}'. If this is not correct, pass --lang or add a generate target in spacetime.json.

What it means

When `--lang` is not given, generate guesses the client language from marker files in the client project directory (the config dir, or the current directory if none): `package.json` means TypeScript, `Cargo.toml` means Rust, and any `*.csproj` means C#. If the directory contains none of these markers, detection fails and generate asks you to be explicit. Note the order — a directory with both package.json and Cargo.toml is detected as TypeScript.

Source

Thrown at crates/cli/src/subcommands/generate.rs:422

    Ok(runs)
}

fn detect_default_language(client_project_dir: &Path) -> anyhow::Result<Language> {
    if client_project_dir.join("package.json").exists() {
        return Ok(Language::TypeScript);
    }
    if client_project_dir.join("Cargo.toml").exists() {
        return Ok(Language::Rust);
    }
    if let Ok(entries) = fs::read_dir(client_project_dir)
        && entries
            .flatten()
            .any(|entry| entry.path().extension().is_some_and(|e| e == "csproj"))
    {
        return Ok(Language::Csharp);
    }

    anyhow::bail!(
        "Could not auto-detect client language from '{}'. \
         If this is not correct, pass --lang or add a generate target in spacetime.json.",
        client_project_dir.display()
    );
}

fn language_cli_name(lang: Language) -> &'static str {
    match lang {
        Language::Rust => "rust",
        Language::Csharp => "csharp",
        Language::TypeScript => "typescript",
        Language::UnrealCpp => "unrealcpp",
    }
}

pub fn default_out_dir_for_language(lang: Language) -> Option<PathBuf> {
    match lang {
        Language::Rust | Language::TypeScript => Some(PathBuf::from("src/module_bindings")),

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Pass `--lang rust` (or csharp / typescript / unrealcpp) explicitly
  2. Add a generate target with a `lang` field to spacetime.json so detection is never needed
  3. Run generate from the directory containing package.json / Cargo.toml / *.csproj

Example fix

# before — in a dir with no package.json/Cargo.toml/*.csproj
spacetime generate

# after
spacetime generate --lang typescript
Defensive patterns

Strategy: validation

Validate before calling

# Detect what generate will detect, before running it:
detect_client_language() {
  [[ -f package.json ]] && { echo typescript; return; }
  [[ -f Cargo.toml ]]   && { echo rust; return; }
  ls *.csproj >/dev/null 2>&1 && { echo csharp; return; }
  echo none
}
if [[ -z "$LANG_ARG" ]] && [[ $(detect_client_language) == none ]]; then
  echo "cannot auto-detect language — pass --lang" >&2; exit 2
fi
spacetime generate

Type guard

// Rust: mirror the CLI's detection so callers can decide instead of failing.
fn detect_client_language(dir: &Path) -> Option<&'static str> {
    if dir.join("package.json").exists() { return Some("typescript"); }
    if dir.join("Cargo.toml").exists() { return Some("rust"); }
    if dir.read_dir().ok()?.flatten().any(|e| e.path().extension().is_some_and(|x| x == "csproj")) {
        return Some("csharp");
    }
    None
}

Prevention

When it happens

Trigger: `spacetime generate` with no `--lang` in an empty or freshly created client directory; a client written in a language with no bindings support (e.g. only .py/.go files); running outside the directory that holds the marker files.

Common situations: First run in a brand-new repo scaffolded by hand; client living in a subdirectory not covered by config-dir; marker files removed during a migration; monorepos where the root has no client markers.

Related errors


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