clockworklabs/SpacetimeDB · error · anyhow::Error

Invalid repository format. Use 'owner/repo' or full git clon

Error message

Invalid repository format. Use 'owner/repo' or full git clone URL

What it means

When a template reference is not a full git URL, init expects the `owner/repo` shorthand and expands it to `https://github.com/owner/repo`. Input that neither starts with `git@`/`ssh://`/`http://`/`https://` nor contains a slash is rejected before any clone is attempted. A bare repo name like `my-template` is the classic trigger.

Source

Thrown at crates/cli/src/subcommands/init.rs:999

        Some(value) if value.eq_ignore_ascii_case("csharp") || value.eq_ignore_ascii_case("c#") => "C#".to_string(),
        Some(value) if value.eq_ignore_ascii_case("typescript") => "TypeScript".to_string(),
        Some(value) if value.eq_ignore_ascii_case("cpp") || value.eq_ignore_ascii_case("c++") => "C++".to_string(),
        Some(value) if !value.trim().is_empty() => value.to_string(),
        _ => "None".to_string(),
    }
}

fn clone_github_template(repo_input: &str, target: &Path, is_server_only: bool) -> anyhow::Result<()> {
    let is_git_url = |s: &str| {
        s.starts_with("git@") || s.starts_with("ssh://") || s.starts_with("http://") || s.starts_with("https://")
    };

    let repo_url = if is_git_url(repo_input) {
        repo_input.to_string()
    } else if repo_input.contains('/') {
        format!("https://github.com/{}", repo_input)
    } else {
        anyhow::bail!("Invalid repository format. Use 'owner/repo' or full git clone URL");
    };

    println!("  Cloning from {}...", repo_url);

    let temp_dir = tempfile::tempdir()?;

    let mut builder = git2::build::RepoBuilder::new();

    let mut fetch_options = git2::FetchOptions::new();
    let mut callbacks = git2::RemoteCallbacks::new();

    callbacks.credentials(|_url, username_from_url, allowed_types| {
        if allowed_types.contains(git2::CredentialType::SSH_KEY)
            && let Some(username) = username_from_url
        {
            return git2::Cred::ssh_key_from_agent(username);
        }
        if allowed_types.contains(git2::CredentialType::USER_PASS_PLAINTEXT) {

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Use the shorthand with an owner: `--template clockworklabs/quickstart`
  2. Or pass a full URL: `https://github.com/owner/repo`, or `git@github.com:owner/repo.git`
  3. If you meant a builtin template, use its catalog id shown by `spacetime init --template=`

Example fix

# before
spacetime init my-app --non-interactive --template quickstart-multiplayer

# after — owner/repo shorthand
spacetime init my-app --non-interactive --template clockworklabs/quickstart-multiplayer

# after — full URL
spacetime init my-app --non-interactive --template https://github.com/clockworklabs/quickstart-multiplayer
Defensive patterns

Strategy: validation

Validate before calling

# Validate the template reference before init:
ref="$TEMPLATE"
case "$ref" in
  git@*|ssh://*|http://*|https://*) ;;           # full URL
  */*) ref="https://github.com/$ref" ;;          # owner/repo shorthand
  *) echo "invalid template ref '$ref' — use owner/repo or a full git URL" >&2; exit 2 ;;
esac
spacetime init my-app --non-interactive --template "$ref"

Type guard

// Rust: accepts git/ssh/http(s) URLs or owner/repo shorthand.
fn is_valid_repo_ref(s: &str) -> bool {
    let s = s.trim();
    s.starts_with("git@")
        || s.starts_with("ssh://")
        || s.starts_with("http://")
        || s.starts_with("https://")
        || s.split('/').count() == 2 && !s.is_empty()
}

Try / catch

#!/usr/bin/env bash
if ! spacetime init my-app --non-interactive --template "$TEMPLATE" 2>err.log; then
  if grep -q "Invalid repository format" err.log; then
    echo "'$TEMPLATE' needs an owner: use owner/repo or a full URL" >&2
    exit 2
  fi
  cat err.log >&2; exit 1
fi

Prevention

When it happens

Trigger: `spacetime init my-app --template my-template` (no owner, no slash); copy-paste that lost the owner part; passing a template id from the catalog where a git reference was expected.

Common situations: Assuming the template name alone identifies a repo; truncating URLs when copying; confusing catalog template ids with git shorthands.

Related errors


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