linera-io/linera-protocol · error · EvmExecutionError
The function {0} is being called but is missing from the byt
Error message
The function {0} is being called but is missing from the bytecode API What it means
Before the system invokes one of the Linera base-contract functions on an EVM module (execute_message, process_streams, summarize_events), ensure_selector_presence scans the deployed bytecode for the PUSH4 + selector byte sequence (has_selector). If the sequence is absent the module does not implement that function and the call fails with MissingFunction instead of executing a call that would revert or misbehave.
Source
Thrown at linera-execution/src/evm/inputs.rs:204
}
pub(crate) fn ensure_message_length(
actual_length: usize,
min_length: usize,
) -> Result<(), EvmExecutionError> {
ensure!(
actual_length >= min_length,
EvmExecutionError::OperationIsTooShort
);
Ok(())
}
pub(crate) fn ensure_selector_presence(
module: &[u8],
selector: &[u8],
fct_name: &str,
) -> Result<(), EvmExecutionError> {
ensure!(
has_selector(module, selector),
EvmExecutionError::MissingFunction(fct_name.to_string())
);
Ok(())
}
pub(crate) fn has_selector(module: &[u8], selector: &[u8]) -> bool {
let push4 = 0x63; // An EVM instruction
let mut vec = vec![push4];
vec.extend(selector);
module.windows(5).any(|window| window == vec)
}
pub(crate) fn get_revm_instantiation_bytes(value: Vec<u8>) -> Vec<u8> {
use alloy_primitives::Bytes;
use alloy_sol_types::{sol, SolCall};
sol! {
function instantiate(bytes value);View on GitHub (pinned to 6c226ddcb3)
Solutions
- Inherit the Linera EVM base contract or manually implement execute_message(bytes), process_streams(...) and summarize_events(...) so their selectors exist in the deployed bytecode
- Before publishing, scan the bytecode for each required PUSH4 + selector sequence (same check as has_selector in linera-execution/src/evm/inputs.rs:211)
- Confirm you published the correct blob type for each side (contract vs service bytecode)
- Recompile against the current Linera Solidity SDK so the ABI signatures match
Example fix
// before: plain contract, no Linera entry points
contract MyApp { function doThing() external {} }
// after: inherit the base app so required selectors exist in bytecode
contract MyApp is LineraApp {
function execute_message(bytes calldata value) external { /* ... */ }
function process_streams(StreamUpdate[] calldata streams) external { /* ... */ }
function summarize_events(StreamUpdate[] calldata streams) external { /* ... */ }
} Defensive patterns
Strategy: validation
Validate before calling
// Mirror of has_selector: check the published bytecode before deploying (Rust)
fn has_selector(module: &[u8], selector: &[u8]) -> bool {
let mut pattern = vec![0x63u8]; // PUSH4
pattern.extend_from_slice(selector);
module.windows(5).any(|w| w == pattern)
}
let required: &[(&[u8], &str)] = &[
(EXECUTE_MESSAGE_SELECTOR, "execute_message"),
(PROCESS_STREAMS_SELECTOR, "process_streams"),
(SUMMARIZE_EVENTS_SELECTOR, "summarize_events"),
];
for (sel, name) in required {
assert!(has_selector(&contract_bytecode, sel), "missing {name} in bytecode");
}
publish(contract_bytecode)?; Type guard
fn is_missing_function(err: &ExecutionError) -> Option<&str> {
match err {
ExecutionError::EvmError(EvmExecutionError::MissingFunction(name)) => Some(name),
_ => None,
}
} Try / catch
match runtime.receive_message(msg).await {
Ok(()) => {}
Err(ref e) if is_missing_function(e).is_some() => {
log::warn!("bytecode lacks {:?}; redeploy with the base contract", is_missing_function(e));
return Err(e.clone()); // deterministic failure: do not retry
}
Err(e) => return Err(e),
} Prevention
- Always inherit the Linera EVM base contract in Solidity so all system entry points exist
- Add a CI check that scans the built bytecode for the required PUSH4 selector sequences before publishing
- Publish with the SDK build pipeline so contract and service bytecode types cannot be swapped
When it happens
Trigger: Publishing an EVM contract whose runtime bytecode contains no PUSH4 for execute_message(bytes), process_streams(...), or summarize_events(...), then receiving a message or stream update that routes into execute_message/process_streams, or a checkpoint that calls summarize_events.
Common situations: Deploying a plain Ethereum contract that does not inherit the Linera EVM base contract; publishing ServiceBytecode where ContractBytecode/EvmBytecode is expected; upgrading the Linera Solidity SDK where the expected function signature changed; aggressive optimizer or linker settings stripping the entry points.
Related errors
- The balances are incoherent for address {0}, balances {1}, {
- It is illegal to call function execute_message from an opera
- It is illegal to call function process_streams from an opera
- It is illegal to call function summarize_events from an oper
- It is illegal to call function instantiate from an operation
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/ec64f5f56c439b51.
Report an issue: GitHub.