astrid-runtime/astrid · error

FSKit callback probe protocol mismatch

Error message

FSKit callback probe protocol mismatch

What it means

read_callback_response deserializes the framed JSON into StorageFilesystemResponseV2 and requires response.protocol_version to equal STORAGE_FILESYSTEM_PROTOCOL_V2. A different version means the peer speaks an incompatible protocol revision, so the response is rejected rather than misinterpreted.

Solutions

  1. Upgrade the FSKit extension to the build that speaks STORAGE_FILESYSTEM_PROTOCOL_V2
  2. Check for a stale extension binary/process and restart the service so the current one is used
  3. Align the protocol constant across provider and extension (bump both together)
  4. If migrating intentionally, add a version negotiation step before probing

Example fix

// extension side
// before
response.protocolVersion = 1
// after
response.protocolVersion = STORAGE_FILESYSTEM_PROTOCOL_V2
Defensive patterns

Strategy: validation

Validate before calling

fn protocol_ok(resp: &StorageFilesystemResponseV2) -> bool { resp.protocol_version == STORAGE_FILESYSTEM_PROTOCOL_V2 }

Try / catch

if let Err(e) = read_callback_response(&mut stream).await { if e.to_string().contains("protocol mismatch") { report_version_skew(); } }

Prevention

When it happens

Trigger: read_callback_response (called by probe_callback) parses a well-framed response whose protocol_version != STORAGE_FILESYSTEM_PROTOCOL_V2 — typically an older or newer extension responding on the socket.

Common situations: Version skew after upgrading the Rust provider but not the bundled FSKit extension (or vice versa); a legacy V1 responder still running; a test stub hard-coding another version constant.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at crates/astrid-storage-provider-fskit/src/service.rs:254

        StorageFilesystemOutcomeV2::Failure(StorageFilesystemFailureV1 { code, message }) => {
            bail!("FSKit callback probe failed [{code}]: {message}")
        },
    }
}

async fn read_callback_response(stream: &mut LocalStream) -> Result<StorageFilesystemResponseV2> {
    let mut length = [0_u8; 4];
    stream.read_exact(&mut length).await?;
    let length = u32::from_be_bytes(length) as usize;
    if length == 0 || length > MAX_CALLBACK_BYTES {
        bail!("FSKit callback response exceeds the bounded frame size");
    }
    let mut bytes = vec![0_u8; length];
    stream.read_exact(&mut bytes).await?;
    let response: StorageFilesystemResponseV2 =
        serde_json::from_slice(&bytes).context("decode FSKit callback probe")?;
    if response.protocol_version != STORAGE_FILESYSTEM_PROTOCOL_V2 {
        bail!("FSKit callback probe protocol mismatch");
    }
    Ok(response)
}

async fn service_loop(
    listener: &LocalListener,
    launch: &StorageProviderServiceLaunchV1,
    mounted: &mut bool,
) -> Result<()> {
    let mut poll = tokio::time::interval(SERVICE_POLL);
    loop {
        tokio::select! {
            accepted = local_transport::accept(listener) => {
                let mut stream = accepted.context("accept FSKit service control")?;
                let request = read_control(&mut stream).await?;
                let (response, stop) = match request {
                    ControlRequest::Status { token } if token == launch.parent.token => {
                        (ControlResponse::Ready, false)

View on GitHub (pinned to affd8760f4)