clockworklabs/SpacetimeDB · error · anyhow::Error
For some reason, your project has both a `bin` and a `bin~`…
Error message
For some reason, your project has both a `bin` and a `bin~` folder. I don't know which to use, so please delete both and rerun this command so that we can see which is up-to-date.
What it means
Expected C# output locations come in bin/ and bin~ pairs (bin~ is a rename/backup some tooling produces). If both variants of the same output path exist after a successful publish, the CLI cannot tell which is current and aborts instead of guessing which StdbModule.wasm to upload.
Solutions
- Delete both bin and bin~ (and obj, obj~ while at it), then re-run the build/publish.
- If it recurs, find what keeps creating bin~ (sync/backup tool) and exclude the project directory from it.
Example fix
# before spacetime build # after rm -rf bin bin~ obj obj~ spacetime build
Defensive patterns
Strategy: validation
Validate before calling
# Pre-build hygiene: never enter a build with split bin folders
[ ! -d bin ] || [ ! -d bin~ ] || { echo "both bin and bin~ present; cleaning" >&2; rm -rf bin bin~; }
spacetime build Prevention
- Clean bin/bin~ between CI builds (or build in fresh checkouts).
- Identify and configure tools that rename bin to bin~ (backup/sync/AV) to skip the project.
- Treat repeated recurrence as an environment problem, not a CLI problem.
When it happens
Trigger: `spacetime build` succeeds but both e.g. bin/Release/net8.0/wasi-wasm/.../StdbModule.wasm and its bin~ twin exist -- typically after an interrupted build, or a watcher/backup tool renaming bin to bin~ between builds.
Common situations: Interrupted or concurrent builds; editors/antivirus/sync tools renaming directories; repeatedly switching between JIT and AOT build modes in the same tree.
Related errors
- Looks like your project is using the deprecated .NET 7.0…
- Argument must be a ConnectionId
- Argument must be a I128
- Argument must be a I256
- Argument must be a Identity
AI-assisted analysis of clockworklabs/SpacetimeDB@9e0d92412f (2026-08-20).
Data as JSON: /api/errors/709491eef9459a63.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/tasks/csharp.rs:463
)),
// NativeAOT-LLVM outputs to 'native' subdirectory instead of 'publish'
project_path.join(format!(
"bin/{config_name}/{target_framework}/wasi-wasm/{subdir}/StdbModule.wasm"
)),
project_path.join(format!(
"bin~/{config_name}/{target_framework}/wasi-wasm/{subdir}/StdbModule.wasm"
)),
// Also check for raw wasm output without wasi-wasm RID folder (NativeAOT-LLVM sometimes does this)
project_path.join(format!("bin/{config_name}/{target_framework}/native/StdbModule.wasm")),
project_path.join(format!("bin~/{config_name}/{target_framework}/native/StdbModule.wasm")),
];
// Check if both bin and bin~ variants exist for the same output path (indicates a conflict)
for i in (0..possible_output_paths.len()).step_by(2) {
if i + 1 < possible_output_paths.len() {
let bin_path = &possible_output_paths[i];
let bin_tilde_path = &possible_output_paths[i + 1];
if bin_path.exists() && bin_tilde_path.exists() {
anyhow::bail!(concat!(
"For some reason, your project has both a `bin` and a `bin~` folder.\n",
"I don't know which to use, so please delete both and rerun this command so that we can see which is up-to-date."
));
}
}
}
for output_path in &possible_output_paths {
if output_path.exists() {
return Ok(output_path.clone());
}
}
// Diagnostic: list what we expected and what actually exists in the output directories
eprintln!("Build path: {build_path:?}, target_framework: {target_framework}, subdir: {subdir}");
eprintln!("Expected output in one of:");
for p in &possible_output_paths {
eprintln!(" {}", p.display());
}View on GitHub (pinned to 9e0d92412f)