{"record":{"id":"1a1fa6e94c4656d6","repo":"linera-io/linera-protocol","slug":"unexpected-query-response-other","errorCode":null,"errorMessage":"unexpected query response: {other:?}","messagePattern":"unexpected query response: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-bridge/src/monitor/mod.rs","lineNumber":49,"sourceCode":"use linera_core::{client::ChainClient, environment::Environment};\nuse linera_execution::{Query, QueryResponse};\nuse tokio::sync::RwLock;\n\nuse crate::proof::DepositKey;\n\n/// Queries the evm-bridge app to check whether a deposit has been processed on Linera.\npub async fn query_deposit_processed<E: Environment>(\n    chain_client: &ChainClient<E>,\n    bridge_app_id: ApplicationId,\n    deposit_key: &DepositKey,\n) -> anyhow::Result<bool> {\n    let hash_hex = format!(\"0x{}\", hex::encode(deposit_key.hash()));\n    let gql = format!(r#\"{{ isDepositProcessed(hash: \"{hash_hex}\") }}\"#);\n    let query = Query::user_without_abi(bridge_app_id, &GqlRequest { query: gql })?;\n    let (outcome, _) = chain_client.query_application(query, None).await?;\n    let response_bytes = match outcome.response {\n        QueryResponse::User(bytes) => bytes,\n        other => anyhow::bail!(\"unexpected query response: {other:?}\"),\n    };\n    let response: serde_json::Value = serde_json::from_slice(&response_bytes)?;\n    Ok(response[\"data\"][\"isDepositProcessed\"].as_bool() == Some(true))\n}\n\n/// Queries the wrapped-fungible app for its declared source-ERC-20 decimals.\npub async fn query_wrapped_fungible_decimals<E: Environment>(\n    chain_client: &ChainClient<E>,\n    fungible_app_id: ApplicationId,\n) -> anyhow::Result<u8> {\n    let query = Query::user_without_abi(\n        fungible_app_id,\n        &GqlRequest {\n            query: \"{ decimals }\".to_string(),\n        },\n    )?;\n    let (outcome, _) = chain_client.query_application(query, None).await?;\n    let response_bytes = match outcome.response {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-bridge/src/monitor/mod.rs#L31-L67","documentation":"The bridge monitor sent a user application query (isDepositProcessed) to a Linera chain via chain_client.query_application, but the returned QueryOutcome was not QueryResponse::User(bytes). Only the User variant carries a GraphQL service response; receiving another variant means the query was answered (or rejected) at the system level instead of being routed to the application's service.","triggerScenarios":"Calling query_deposit_processed with a bridge_app_id that is not a user application (wrong ApplicationId, or the app was never published/registered on the target chain), or a version/ABI mismatch where the node resolves the query to a system response. The response enum is matched strictly; any non-User variant bails with its Debug form.","commonSituations":"Misconfigured BRIDGE_APP_ID env/config pointing at a fungible-token app id instead of the bridge app; querying a chain where the bridge application was never registered; deployment drift between the relay config and what is actually published on-chain.","solutions":["Verify bridge_app_id: it must be the application id of the published bridge app (match it against the id printed at publish time / the chain's registered applications).","Confirm the target chain actually has the bridge application registered (query the chain's application list) before calling query_deposit_processed.","Redeploy or re-register the application if it is missing, then update the relay configuration.","Handle the error at the call site: treat any non-User response as a configuration fault and stop rather than retry, since retrying with the same ids cannot succeed."],"exampleFix":"// before\nlet (outcome, _) = chain_client.query_application(query, None).await?;\nlet QueryResponse::User(bytes) = outcome.response else {\n    anyhow::bail!(\"unexpected query response: {:?}\", outcome.response);\n};\n\n// after: fail with actionable context\nlet QueryResponse::User(bytes) = outcome.response else {\n    anyhow::bail!(\n        \"bridge app {bridge_app_id} did not return a user query response \\\n         (got {:?}); is the application registered on chain {}?\",\n        outcome.response, chain_client.chain_id()\n    );\n};","handlingStrategy":"try-catch","validationCode":"// Before starting the monitor, verify the bridge app is registered on the target chain\n// (e.g. query the chain's applications and assert bridge_app_id is present),\n// so query_deposit_processed cannot hit a system-level response.","typeGuard":null,"tryCatchPattern":"match monitor.query_deposit_processed(&key).await {\n    Ok(processed) => processed,\n    Err(e) if e.to_string().contains(\"unexpected query response\") => {\n        // configuration fault: wrong/unregistered app id — do NOT retry blindly\n        tracing::error!(%bridge_app_id, \"bridge app not answering user queries; check registration\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Pin app ids in one config source and validate them at relay startup with a smoke query.","Fail relay startup early if the bridge app fails a trivial user query instead of discovering it mid-operation."],"tags":["linera-bridge","query","application-id","configuration","rust"],"backgroundTag":"unexpected-response-type","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}