clockworklabs/SpacetimeDB · error

Failed to canonicalize path {}: {}

Error message

Failed to canonicalize path {}: {}

What it means

Build-time panic in crates/cli/build.rs: canonicalizing `{repo_root}/templates/{relative_path}` failed in `get_full_path_within_manifest_dir`. Every template referenced from templates-list.json is resolved to an absolute canonical path before listing its files; canonicalize fails when that path doesn't exist (dangling component), so this fires when the list references a template directory that is absent on disk.

Source

Thrown at crates/cli/build.rs:376

                file_path.display(),
            )
        });
        if file_type.is_dir() {
            ls_recursively(&file_path, repo_root, out);
        } else {
            out.push(make_repo_root_relative(&file_path, repo_root));
        }
    }
}

/// Treat `relative_path` as a relative path within the repo root's templates directory
/// and transform it into an absolute, canonical path.
fn get_full_path_within_manifest_dir(relative_path: &Path, _manifest_dir: &Path) -> PathBuf {
    let repo_root = get_repo_root();
    let full_path = repo_root.join("templates").join(relative_path);

    full_path.canonicalize().unwrap_or_else(|e| {
        panic!("Failed to canonicalize path {}: {}", full_path.display(), e);
    })
}

/// Transform `full_path` into a relative path within `repo_root`.
///
/// `full_path` and `repo_root` should both be canonical paths, as by [`Path::canonicalize`].
fn make_repo_root_relative(full_path: &Path, repo_root: &Path) -> PathBuf {
    full_path
        .strip_prefix(repo_root)
        .map(|p| p.to_path_buf())
        .unwrap_or_else(|_| {
            panic!(
                "Path {} is outside repo root {}",
                full_path.display(),
                repo_root.display()
            )
        })
}

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Compare the panic's path against disk: `ls <printed-path>`; create the directory or fix the JSON entry.
  2. Validate every entry resolves: `jq -r '.templates[].directory' templates/templates-list.json | while read d; do test -d "templates/$d" || echo "missing: $d"; done`.
  3. Ensure the build context includes the whole templates/ tree.
  4. Check exact casing of folder names when building on case-sensitive filesystems.

Example fix

# before: templates-list.json says directory "chat-console" but disk has "chat-console-rs"
# after: fix the entry
jq 'map(if .directory == "chat-console" then .directory = "chat-console-rs" else . end)' templates/templates-list.json
Defensive patterns

Strategy: validation

Validate before calling

# Validate all template list entries resolve before building:
jq -r '.templates[].directory' templates/templates-list.json | while read -r d; do
  realpath -e "templates/$d" >/dev/null 2>&1 || echo "unresolvable: templates/$d"
done

Prevention

When it happens

Trigger: templates/templates-list.json contains an entry whose directory field has no matching folder under templates/ (typo, renamed folder, not yet created); the templates directory was excluded from the build context; case-sensitivity mismatch between the JSON entry and the folder name.

Common situations: Editing the JSON list before creating the folder; sparse checkouts or Docker contexts omitting templates subdirectories; developing on case-insensitive macOS then building on case-sensitive Linux.

Related errors


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