{"record":{"id":"1e9e2793aea458b6","repo":"linera-io/linera-protocol","slug":"query-argument-is-invalid-and-could-not-be-des","errorCode":null,"errorMessage":"Query {argument:?} is invalid and could not be deserialized","messagePattern":"Query (.+?) is invalid and could not be deserialized","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-sdk/src/service/mod.rs","lineNumber":46,"sourceCode":"///\n/// Generates the necessary boilerplate for implementing the service WIT interface, exporting the\n/// necessary resource types and functions so that the host can call the application service.\n#[macro_export]\nmacro_rules! service {\n    ($service:ident) => {\n        #[doc(hidden)]\n        static mut SERVICE: Option<$service> = None;\n\n        /// Export the service interface.\n        $crate::export_service!($service with_types_in $crate::service::wit);\n\n        /// Mark the service type to be exported.\n        impl $crate::service::wit::exports::linera::app::service_entrypoints::Guest for $service {\n            fn handle_query(argument: Vec<u8>) -> Vec<u8> {\n                use $crate::util::BlockingWait as _;\n                $crate::ServiceLogger::install();\n                let request = $crate::serde_json::from_slice(&argument)\n                    .unwrap_or_else(|_| panic!(\"Query {argument:?} is invalid and could not be deserialized\"));\n                let response = $crate::service::run_async_entrypoint(\n                    unsafe { &mut SERVICE },\n                    move |service| service.handle_query(request).blocking_wait(),\n                );\n                $crate::serde_json::to_vec(&response)\n                    .expect(\"Failed to serialize query response\")\n            }\n        }\n\n        /// Stub of a `main` entrypoint so that the binary doesn't fail to compile on targets other\n        /// than WebAssembly.\n        #[cfg(not(target_arch = \"wasm32\"))]\n        fn main() {}\n    };\n}\n\n/// Runs an asynchronous entrypoint in a blocking manner, by repeatedly polling the entrypoint\n/// future.","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-sdk/src/service/mod.rs#L28-L64","documentation":"The linera-sdk service entrypoint macro deserializes incoming query bytes with serde_json into the app's Query type before calling handle_query. Bytes that are not valid JSON for that type panic the service guest with 'Query ... is invalid and could not be deserialized'. The request reaches the application service through GraphQL queries against the chain.","triggerScenarios":"Sending a GraphQL query (chain application service query) whose argument string is not valid JSON for the app's declared Query type: wrong field names/types, extra/missing fields, or an entirely different shape (e.g. reusing an operation-style argument for a query).","commonSituations":"Frontends sending snake_case where the app's serde config expects camelCase (or vice versa); querying a newly published app with arguments designed for its previous version; examples like fungible/counters where each app has its own Query enum variants.","solutions":["Match the JSON exactly to the app's Query type: correct variant names, field names, and casing","Test the serialization client-side first: serde_json::from_slice::<Query>(bytes) must succeed before sending","For enum queries use the tagged form the app's serde attributes produce (e.g. {\"variant\":{...}})","Update query senders whenever the app's Query type changes and is re-published"],"exampleFix":"// before (wrong shape for enum Query)\nlet bytes = br#\"{\"account\": \"0xab..\"}\"#;\n\n// after (correct serde_enum tagged form)\nlet bytes = serde_json::to_vec(&Query::Balance { owner })?; // e.g. {\"balance\":{\"owner\":\"0xab..\"}}","handlingStrategy":"validation","validationCode":"// Client-side, before sending a query to the service:\nlet payload = serde_json::to_string(&query)?;\nserde_json::from_str::<app::Query>(&payload)\n    .expect(\"payload must round-trip as the app's Query type\");\n// now safe to submit via GraphQL","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate query payloads with serde from the app's Query type","Respect the app's serde casing/tag attributes when constructing JSON by hand","Log the exact payload when a query fails so mismatches are diffable against the ABI"],"tags":["sdk","serde","json","graphql","service","query"],"backgroundTag":"json-deserialization-failed","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}