astrid-runtime/astrid · error

{provider_name} returned a response for a different request

Error message

{provider_name} returned a response for a different request

What it means

validate_response in crates/astrid-cli/src/commands/storage.rs enforces that a native storage provider's response echoes the request_id of the request that was sent. When response.request_id differs from request.request_id, the CLI bails because the response cannot be trusted to correspond to the operation performed — it may be a stale, replayed, or crossed-wire response from another invocation.

Source

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

        ),
    })
}

fn validate_response(
    provider_name: &str,
    request: &StorageProviderRequestV1,
    response: &StorageProviderResponseV1,
    required_capabilities: &[StorageProviderCapabilityV1],
) -> Result<()> {
    if response.protocol_version != STORAGE_PROVIDER_PROTOCOL_V1 {
        bail!(
            "{provider_name} protocol mismatch: expected {}, received {}",
            STORAGE_PROVIDER_PROTOCOL_V1,
            response.protocol_version
        );
    }
    if response.request_id != request.request_id {
        bail!("{provider_name} returned a response for a different request");
    }
    if response.provider.name != provider_name
        || response.provider.version.is_empty()
        || response.provider.version.len() > 128
        || response.provider.version.chars().any(char::is_control)
        || response.provider.capabilities.len() > 16
        || !capabilities_are_unique(&response.provider.capabilities)
    {
        bail!("native provider identity does not match the co-installed executable");
    }
    for capability in required_capabilities {
        if !response.provider.capabilities.contains(capability) {
            bail!("{provider_name} does not advertise required capability {capability:?}");
        }
    }
    let operation_matches = matches!(
        (&request.operation, &response.outcome),
        (

View on GitHub (pinned to affd8760f4)

Solutions

  1. Fix the provider binary to echo the exact request_id from the request into the response envelope
  2. Ensure only one provider request is in flight per spawned provider process, or correlate responses strictly by request_id
  3. Rebuild/reinstall the co-installed provider so its version matches the CLI's protocol V1 expectations
  4. Add a test in the provider asserting response.request_id == request.request_id for every operation

Example fix

// before (provider side)
let response = StorageProviderResponseV1 { request_id: Uuid::nil(), .. };
// after
let response = StorageProviderResponseV1 { request_id: request.request_id, .. };
Defensive patterns

Strategy: validation

Validate before calling

fn request_id_matches(req: &StorageProviderRequestV1, resp: &StorageProviderResponseV1) -> bool { resp.request_id == req.request_id }

Type guard

fn is_response_for(req: &StorageProviderRequestV1, resp: &StorageProviderResponseV1) -> bool { resp.request_id == req.request_id }

Try / catch

let resp = run_provider(req).context("provider call failed")?;
anyhow::ensure!(resp.request_id == req.request_id, "provider response request_id mismatch");

Prevention

When it happens

Trigger: A native storage provider binary (invoked via the V1 protocol) replies with a response envelope whose request_id does not equal the request_id stamped on the outgoing StorageProviderOperationV1 request. Detected in validate_response, called from run and provider_response_binds_protocol_identity_capability_and_request.

Common situations: A buggy or hand-written provider implementation forgets to copy request_id into the response; a provider caches and replays responses; async/stdout interleaving causes responses from two concurrent provider calls to be swapped; the provider deserializes the request into the wrong struct and emits a default request_id.

Related errors


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