linera-io/linera-protocol · critical
Application parameters must be deserializable
Error message
Application parameters must be deserializable
What it means
ContractRuntime::application_parameters (linera-sdk/src/contract/runtime.rs:78) lazily fetches the creation-time parameter bytes from the host and deserializes them with serde_json into Application::Parameters, expecting success. The panic fires when those bytes were produced from a different Parameters type than the contract declares - field renames, missing fields, or wrong JSON types. Because this runs inside contract execution, a mismatch fails the whole operation.
Source
Thrown at linera-sdk/src/contract/runtime.rs:83
}
/// Returns a storage context suitable for a root view.
pub fn root_view_storage_context(&self) -> ViewStorageContext {
ViewStorageContext::new_unchecked(self.key_value_store(), Vec::new(), ())
}
}
impl<Application> ContractRuntime<Application>
where
Application: Contract,
{
/// Returns the application parameters provided when the application was created.
pub fn application_parameters(&mut self) -> Application::Parameters {
self.application_parameters
.get_or_insert_with(|| {
let bytes = base_wit::application_parameters();
serde_json::from_slice(&bytes)
.expect("Application parameters must be deserializable")
})
.clone()
}
/// Returns the ID of the current application.
pub fn application_id(&mut self) -> ApplicationId<Application::Abi> {
*self
.application_id
.get_or_insert_with(|| ApplicationId::from(base_wit::get_application_id()).with_abi())
}
/// Returns the chain ID of the current application creator.
pub fn application_creator_chain_id(&mut self) -> ChainId {
*self
.application_creator_chain_id
.get_or_insert_with(|| base_wit::get_application_creator_chain_id().into())
}
View on GitHub (pinned to 6c226ddcb3)
Solutions
- Define Parameters once in the application's shared crate and serialize creation parameters from that same type.
- Validate the JSON against the contract's Parameters before creating the application (serde round-trip in a test).
- If Parameters changed, publish and create a new application instance rather than reusing the old one.
- Check field naming (serde rename attributes) between the JSON and the struct.
Example fix
// before: hand-written JSON at creation
// linera publish-application ... --json-parameters '{"fee": 5}'
// contract expects: struct Parameters { fee_percent: u64 }
// after: derive JSON from the shared type
let params = my_app::Parameters { fee_percent: 5 };
let json = serde_json::to_string(¶ms)?; // guaranteed to match the contract's type Defensive patterns
Strategy: validation
Validate before calling
// At application-creation time, build parameters from the same type the contract uses: use my_app_abi::Parameters; let json = serde_json::to_string(¶meters)?; // off-chain round-trip proves the contract's deserialization will succeed serde_json::from_str::<Parameters>(&json)?;
Type guard
fn parameters_round_trip(p: &Parameters) -> bool {
serde_json::to_string(p).ok().and_then(|s| serde_json::from_str::<Parameters>(&s).ok()).is_some()
} Try / catch
// The expect runs inside the contract runtime; there is no catch on the caller side. // Validate the JSON against the contract's Parameters before creating the application, // and never change the Parameters type of a live application.
Prevention
- Define Parameters once in the shared crate and serialize creation arguments from it.
- Do not hand-edit --json-parameters strings; generate them with a small script or CLI built on the shared crate.
- After changing Parameters, publish and instantiate a new application rather than mutating the old one.
- Include a serde round-trip unit test for Parameters in the application's test suite.
When it happens
Trigger: The application was created with --json-parameters (or programmatically serialized parameters) whose JSON does not match the contract's Parameters type: renamed/missing fields, wrong types, or parameters built by an older version of the application's shared crate.
Common situations: Passing hand-written JSON parameters at publish time that drift from the struct; upgrading the application's Parameters type without recreating the application; frontend and contract using different shared-crate versions.
Related errors
- Failed to deserialize `Operation` in execute_operation
- Failed to deserialize message
- Failed to deserialize service response
- Application parameters must be deserializable
- Failed to deserialize query response from application
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/a6a2c41ee7b9ffa5.
Report an issue: GitHub.