{"record":{"id":"d7edd26fc8642ef6","repo":"astrid-runtime/astrid","slug":"native-provider-identity-does-not-match-the-co-ins","errorCode":null,"errorMessage":"native provider identity does not match the co-installed executable","messagePattern":"native provider identity does not match the co-installed executable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/storage.rs","lineNumber":232,"sourceCode":") -> Result<()> {\n    if response.protocol_version != STORAGE_PROVIDER_PROTOCOL_V1 {\n        bail!(\n            \"{provider_name} protocol mismatch: expected {}, received {}\",\n            STORAGE_PROVIDER_PROTOCOL_V1,\n            response.protocol_version\n        );\n    }\n    if response.request_id != request.request_id {\n        bail!(\"{provider_name} returned a response for a different request\");\n    }\n    if response.provider.name != provider_name\n        || response.provider.version.is_empty()\n        || response.provider.version.len() > 128\n        || response.provider.version.chars().any(char::is_control)\n        || response.provider.capabilities.len() > 16\n        || !capabilities_are_unique(&response.provider.capabilities)\n    {\n        bail!(\"native provider identity does not match the co-installed executable\");\n    }\n    for capability in required_capabilities {\n        if !response.provider.capabilities.contains(capability) {\n            bail!(\"{provider_name} does not advertise required capability {capability:?}\");\n        }\n    }\n    let operation_matches = matches!(\n        (&request.operation, &response.outcome),\n        (\n            StorageProviderOperationV1::Mount { .. },\n            StorageProviderOutcomeV1::Success(StorageProviderSuccessV1::Mounted { .. })\n        ) | (\n            StorageProviderOperationV1::Sync { .. },\n            StorageProviderOutcomeV1::Success(StorageProviderSuccessV1::Synced { .. })\n        ) | (\n            StorageProviderOperationV1::Status { .. },\n            StorageProviderOutcomeV1::Success(StorageProviderSuccessV1::Status { .. })\n        ) | (","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/storage.rs#L214-L250","documentation":"After checking the protocol version, validate_response validates the provider identity block returned by the native provider: the provider name must match the co-installed executable's expected name, the version string must be non-empty, at most 128 chars, free of control characters, and the capability list must have at most 16 unique entries. Any violation bails with this error because a mismatched identity means the response may come from a different (possibly malicious or stale) provider binary.","triggerScenarios":"The provider response's provider.name differs from the invoked provider_name, or version is empty/too long/contains control chars, or capabilities list exceeds 16 entries or contains duplicates — checked in validate_response.","commonSituations":"A leftover or replaced provider binary of a different build sits at the co-install path; a provider sends a debug version string with newline/control characters; a provider pads its capability list with duplicate entries; PATH or install layout points at an old provider version.","solutions":["Reinstall the co-installed native provider so name/version match what the CLI expects","Fix the provider to emit a clean, non-empty version string without control characters and a deduplicated capability list","Verify the provider binary path resolution isn't picking up a stale binary from another install","Add provider-side validation that sanitizes version and deduplicates capabilities before responding"],"exampleFix":"// before\ncapabilities: vec![\"mount\".into(), \"mount\".into(), \"unmount\".into()],\n// after\ncapabilities: vec![\"mount\".into(), \"unmount\".into()],","handlingStrategy":"validation","validationCode":"fn identity_ok(name: &str, p: &StorageProviderIdentityV1) -> bool { p.name == name && !p.version.is_empty() && p.version.len() <= 128 && !p.version.chars().any(char::is_control) && p.capabilities.len() <= 16 }","typeGuard":"fn has_unique_capabilities(caps: &[String]) -> bool { caps.len() <= 16 && caps.iter().collect::<std::collections::HashSet<_>>().len() == caps.len() }","tryCatchPattern":"match validate_provider_identity(&resp.provider, expected_name) {\n    Ok(()) => {},\n    Err(e) => eprintln!(\"reinstall the storage provider: {e}\"),\n}","preventionTips":["Keep provider binary and CLI installed as a matched pair","Sanitize version strings (no control chars, <=128 chars) in the provider","Deduplicate capability lists before serializing responses"],"tags":["ipc","identity-validation","native-provider"],"backgroundTag":"schema-validation-failed","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}