linera-io/linera-protocol · error

Failed to deserialize instantiation argument {argument:?}

Error message

Failed to deserialize instantiation argument {argument:?}

What it means

The linera-sdk contract entrypoint macro deserializes the raw instantiate argument bytes with serde_json into the application's generated InstantiateArgument type. If the bytes are not valid JSON for that exact type, the generated entrypoint panics. This happens inside the contract's Wasm/EVM sandbox, so the failure aborts the operation and is reported back through block execution.

Source

Thrown at linera-sdk/src/contract/mod.rs:51

macro_rules! contract {
    ($contract:ident) => {
        #[doc(hidden)]
        static mut CONTRACT: Option<$contract> = None;

        /// Export the contract interface.
        $crate::export_contract!($contract with_types_in $crate::contract::wit);

        /// Mark the contract type to be exported.
        impl $crate::contract::wit::exports::linera::app::contract_entrypoints::Guest
            for $contract
        {
            fn instantiate(argument: Vec<u8>) {
                use $crate::util::BlockingWait as _;
                $crate::contract::run_async_entrypoint::<$contract, _, _>(
                    unsafe { &mut CONTRACT },
                    move |contract| {
                        let argument = $crate::serde_json::from_slice(&argument)
                            .unwrap_or_else(|_| panic!("Failed to deserialize instantiation argument {argument:?}"));

                        contract.instantiate(argument).blocking_wait()
                    },
                )
            }

            fn execute_operation(operation: Vec<u8>) -> Vec<u8> {
                use $crate::util::BlockingWait as _;
                $crate::contract::run_async_entrypoint::<$contract, _, _>(
                    unsafe { &mut CONTRACT },
                    move |contract| {
                        let operation = <$contract as $crate::abi::ContractAbi>::deserialize_operation(operation)
                            .expect("Failed to deserialize `Operation` in execute_operation");

                        let response = contract.execute_operation(operation).blocking_wait();

                        <$contract as $crate::abi::ContractAbi>::serialize_response(response)
                            .expect("Failed to serialize `Response` in execute_operation")

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Serialize the argument with serde_json from the app's exact InstantiateArgument type (in the app's tests) and pass that JSON verbatim
  2. Check every field name and type against the app's struct definition (serde renames included)
  3. For a unit-like argument pass {} or omit the argument entirely per the app's docs
  4. If the app was recently changed, re-publish and re-create with arguments matching the new ABI

Example fix

// before (caller passes mismatched JSON)
let argument = br"[1, 2, 3]"; // expected struct { name: String, value: u64 }

// after
#[derive(Serialize)]
struct Args { name: String, value: u64 }
let argument = serde_json::to_vec(&Args { name: "test".into(), value: 1 })?;
Defensive patterns

Strategy: validation

Validate before calling

// Client-side, before publishing/creating the contract:
let bytes = serde_json::to_vec(&argument)?;
serde_json::from_slice::<app::InstantiationArgument>(&bytes)
    .expect("argument must round-trip as the app's InstantiateArgument type");
// now safe to pass `bytes`

Prevention

When it happens

Trigger: Creating/publishing a contract with an instantiation argument that does not match the app's declared type: passing BCS or hex-encoded bytes instead of JSON, wrong field names, wrong field types, or a JSON shape from an older version of the app's ABI.

Common situations: Using --json-argument with a hand-written JSON whose keys don't match the struct; the app changed InstantiateArgument between versions but callers still send the old shape; passing [] or a bare number where a struct/unit object {} is expected; copy-pasting arguments between different example apps.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/df5552d921590a28. Report an issue: GitHub.