clockworklabs/SpacetimeDB · error · anyhow::Error

Either --out-dir or --uproject-dir is required

Error message

Either --out-dir or --uproject-dir is required

What it means

generate resolves the output directory through a chain: `out-dir`, then `uproject-dir`, then a per-language default (`src/module_bindings` for Rust/TypeScript, `module_bindings` for C#). UnrealCpp intentionally has no default because output belongs inside the UE project, so a run whose language resolves to unrealcpp with no usable `out-dir` or `uproject-dir` is rejected. In practice this fires when a configured uproject-dir exists as a value but fails path resolution, since a fully missing uproject-dir is caught earlier by the dedicated unrealcpp validation.

Source

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

                println!(
                    "Detected client language '{}' from '{}'. If this is not correct, pass --lang or add a generate target in spacetime.json.",
                    language_cli_name(detected),
                    client_project_dir.display()
                );
                detected
            }
        };

        let out_dir = command_config
            .get_resolved_path("out_dir", config_dir)?
            .or_else(|| {
                command_config
                    .get_resolved_path("uproject_dir", config_dir)
                    .ok()
                    .flatten()
            })
            .or_else(|| default_out_dir_for_language(lang).map(|p| config_dir.map(|d| d.join(&p)).unwrap_or(p)))
            .ok_or_else(|| anyhow::anyhow!("Either --out-dir or --uproject-dir is required"))?;

        let include_private = command_config.get_one::<bool>("include_private")?.unwrap_or(false);

        runs.push(GenerateRunConfig {
            project_path,
            wasm_file,
            js_file,
            lang,
            namespace,
            module_name,
            module_prefix,
            build_options,
            dotnet_version,
            out_dir,
            include_private,
        });
    }

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Pass `--out-dir <path>` explicitly
  2. Fix the `uproject-dir` value in spacetime.json so it resolves from the directory generate runs in (prefer relative paths)
  3. Remove empty-string `out-dir`/`uproject-dir` entries from spacetime.json so the fallback chain can work

Example fix

// spacetime.json — before (empty values defeat the fallback chain)
{ "generate": { "targets": [ { "database": "mydb", "lang": "unrealcpp", "uproject-dir": "" } ] } }

// spacetime.json — after
{ "generate": { "targets": [ { "database": "mydb", "lang": "unrealcpp", "uproject-dir": "../MyGame" } ] } }
Defensive patterns

Strategy: validation

Validate before calling

# Ensure an output location exists for languages without a default (unrealcpp):
if [[ "$LANG_ARG" == "unrealcpp" && -z "$OUT_DIR" && -z "$UPROJECT_DIR" ]]; then
  echo "unrealcpp has no default out-dir — pass --out-dir or --uproject-dir" >&2
  exit 2
fi
# Also reject empty-string values in spacetime.json:
jq -e '.generate.targets[]? | select((."out-dir" // "x") == "" or (."uproject-dir" // "x") == "")' spacetime.json >/dev/null \
  && { echo "empty out-dir/uproject-dir in spacetime.json" >&2; exit 2; }

Prevention

When it happens

Trigger: An unrealcpp run where `uproject-dir` is set in spacetime.json/CLI but cannot be resolved to a path; an empty or malformed `out-dir` value together with an unresolvable `uproject-dir`; any future language registered without a default out-dir.

Common situations: spacetime.json entries with empty-string out-dir/uproject-dir values; paths that depend on a different working directory; configs moved between machines with different absolute paths.

Related errors


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