clockworklabs/SpacetimeDB · warning · anyhow::Error

Publish aborted by user.

Error message

Publish aborted by user.

What it means

Before uploading a module, `spacetime publish` resolves the target database host and, when it is anything other than localhost/127.0.0.1, prints 'You are about to publish to a non-local server' and asks 'Are you sure you want to proceed?'. This error means the prompt was declined (answer other than 'y'), so nothing was uploaded. It is a safety gate against accidentally pushing modules to a shared or production server.

Solutions

  1. Re-run the command and answer 'y' at the prompt if the remote target is intended.
  2. Pass `--yes=remote` (or `--yes=all`) to skip this specific prompt in automation.
  3. If the remote target is NOT intended, publish with `--server local` or run `spacetime server set-default local` first.
  4. In CI, always pass the appropriate `--yes=...` value because there is no TTY to confirm on.

Example fix

# before (declines prompt -> error)
spacetime publish mydb
# after (intended remote publish)
spacetime publish mydb --yes=remote
# or, if local was intended
spacetime publish mydb --server local
Defensive patterns

Strategy: validation

Validate before calling

# Resolve the target host before publishing; only prompt-free publish when it is intended
SERVER_URL=$(spacetime server list 2>/dev/null | grep -E '^\*' | awk '{print $NF}')
case "$SERVER_URL" in *localhost*|*127.0.0.1*) ;; *) EXTRA="--yes=remote" ;; esac
spacetime publish mydb $EXTRA

Try / catch

std::process::Command::new("spacetime").args(["publish", db]) ... on non-zero exit, if stderr contains "Publish aborted by user" treat as a deliberate cancel (exit 0 semantics), not a pipeline failure

Prevention

When it happens

Trigger: `spacetime publish` (or `spacetime generate`, which shares this path) where the host resolved from --server, the CLI config default, or the database URL is not localhost/127.0.0.1, run without `--yes=remote`/`--yes=all`, and the user answers 'n' at the confirmation prompt.

Common situations: Default server previously switched to maincloud/testnet/production via `spacetime server set-default`; CI or non-interactive shells where stdin is closed so y_or_n reads as 'no'; forgetting the --yes flag in automation scripts.

Related errors


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

Appendix: source

Thrown at crates/cli/src/subcommands/publish.rs:704

            .await?
        };
        let program_bytes = environment::read_program(&path_to_program)?;
        let module_schema = environment::inspect(&program_bytes, host_type).await?;
        let environment = environment::resolve(
            module_schema.environment(),
            command_config.get_config_value("env"),
            |key| std::env::var_os(key),
        )?;
        print!("{}", environment.display());

        let server_address = {
            let url = Url::parse(&database_host)?;
            url.host_str().unwrap_or("<default>").to_string()
        };
        if server_address != "localhost" && server_address != "127.0.0.1" {
            println!("You are about to publish to a non-local server: {server_address}");
            if !y_or_n(yes.publish_to_remote, "Are you sure you want to proceed?")? {
                anyhow::bail!("Publish aborted by user.");
            }
        }

        println!(
            "Uploading to {} => {}",
            server.unwrap_or(config.default_server_name().unwrap_or("<default>")),
            database_host
        );

        // The body contains secrets. Never replay it to a redirect destination.
        let client = reqwest::Client::builder()
            .redirect(reqwest::redirect::Policy::none())
            .build()?;
        // If a name was given, ensure to percent-encode it.
        // We also use PUT with a name or identity, and POST otherwise.
        let mut builder = if let Some(name_or_identity) = name_or_identity {
            let encode_set = const { &percent_encoding::NON_ALPHANUMERIC.remove(b'_').remove(b'-') };
            let domain = percent_encoding::percent_encode(name_or_identity.as_bytes(), encode_set);

View on GitHub (pinned to eddf9f5014)