astrid-runtime/astrid · error

exited without a successful protocol response

Error message

{provider_name} exited without a successful protocol response: {status}

What it means

After reading the provider's response within the size bound, the runner waits for the child process and requires a zero exit status. A non-success exit is surfaced as "{provider} exited without a successful protocol response: {status}" — the provider itself signaled failure (or crashed) instead of completing the protocol handshake. The response bytes, even if parseable, are not trusted when the process failed.

Solutions

  1. Inspect the provider's stderr output from the run for its own error message and fix the underlying cause.
  2. Run the provider binary directly with the same request JSON to reproduce and debug its non-zero exit.
  3. Verify the provider is installed correctly (executable bit, matching platform/arch) and is a V1-protocol-compatible version.

Example fix

// before
$ astrid storage mount --as alice
error: s3-provider exited without a successful protocol response: exit status: 1

// after
$ s3-provider < request.json   # reproduce directly
Error: missing AWS credentials  # fix credentials, then retry the CLI command
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: run the provider with --version or a trivial request and check exit status
let ok = std::process::Command::new(provider)
    .arg("--version")
    .status()
    .map(|s| s.success())
    .unwrap_or(false);

Try / catch

match run_storage_command(args).await {
    Err(e) if e.to_string().contains("exited without a successful protocol response") => {
        eprintln!("Provider failed; inspect its stderr for the root cause.");
    }
    other => other?,
}

Prevention

When it happens

Trigger: The native provider binary exits non-zero after/while writing its response: it panicked, returned a non-zero code on a storage error, was killed by a signal, or failed to spawn its own work and exited early.

Common situations: Providers crashing on malformed requests; providers exiting 1 to report backend errors (auth failure, missing mount target); exec-format or missing shared library issues causing immediate abnormal exit.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/760846d7fb1ec824. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-cli/src/commands/storage.rs:146

        .context("terminate native provider request")?;
    drop(stdin);
    let stdout = child
        .stdout
        .take()
        .context("native provider stdout is unavailable")?;
    let mut response_bytes = Vec::new();
    stdout
        .take(MAX_PROVIDER_RESPONSE_BYTES + 1)
        .read_to_end(&mut response_bytes)
        .context("read native provider response")?;
    if response_bytes.len() as u64 > MAX_PROVIDER_RESPONSE_BYTES {
        let _ = child.kill();
        let _ = child.wait();
        bail!("{provider_name} exceeded the bounded protocol response size");
    }
    let status = child.wait().context("wait for native storage provider")?;
    if !status.success() {
        bail!("{provider_name} exited without a successful protocol response: {status}");
    }
    let response: StorageProviderResponseV1 =
        serde_json::from_slice(&response_bytes).context("decode native provider response")?;
    validate_response(provider_name, &request, &response, &required_capabilities)?;
    render_response(response.outcome)
}

fn provider_operation(
    command: StorageCommand,
) -> Result<(StorageProviderOperationV1, Vec<StorageProviderCapabilityV1>)> {
    Ok(match command {
        StorageCommand::Mount(args) => {
            let view = args.view()?;
            let access = if args.access(&view) == "read-only" {
                StorageProviderAccessV1::ReadOnly
            } else {
                StorageProviderAccessV1::ReadWrite
            };

View on GitHub (pinned to affd8760f4)