{"record":{"id":"ec64f5f56c439b51","repo":"linera-io/linera-protocol","slug":"the-function-0-is-being-called-but-is-missing-fr","errorCode":null,"errorMessage":"The function {0} is being called but is missing from the bytecode API","messagePattern":"The function (.+?) is being called but is missing from the bytecode API","errorType":"validation","errorClass":"EvmExecutionError","httpStatus":null,"severity":"error","filePath":"linera-execution/src/evm/inputs.rs","lineNumber":204,"sourceCode":"}\n\npub(crate) fn ensure_message_length(\n    actual_length: usize,\n    min_length: usize,\n) -> Result<(), EvmExecutionError> {\n    ensure!(\n        actual_length >= min_length,\n        EvmExecutionError::OperationIsTooShort\n    );\n    Ok(())\n}\n\npub(crate) fn ensure_selector_presence(\n    module: &[u8],\n    selector: &[u8],\n    fct_name: &str,\n) -> Result<(), EvmExecutionError> {\n    ensure!(\n        has_selector(module, selector),\n        EvmExecutionError::MissingFunction(fct_name.to_string())\n    );\n    Ok(())\n}\n\npub(crate) fn has_selector(module: &[u8], selector: &[u8]) -> bool {\n    let push4 = 0x63; // An EVM instruction\n    let mut vec = vec![push4];\n    vec.extend(selector);\n    module.windows(5).any(|window| window == vec)\n}\n\npub(crate) fn get_revm_instantiation_bytes(value: Vec<u8>) -> Vec<u8> {\n    use alloy_primitives::Bytes;\n    use alloy_sol_types::{sol, SolCall};\n    sol! {\n        function instantiate(bytes value);","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-execution/src/evm/inputs.rs#L186-L222","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: plain contract, no Linera entry points\ncontract MyApp { function doThing() external {} }\n\n// after: inherit the base app so required selectors exist in bytecode\ncontract MyApp is LineraApp {\n    function execute_message(bytes calldata value) external { /* ... */ }\n    function process_streams(StreamUpdate[] calldata streams) external { /* ... */ }\n    function summarize_events(StreamUpdate[] calldata streams) external { /* ... */ }\n}","handlingStrategy":"validation","validationCode":"// Mirror of has_selector: check the published bytecode before deploying (Rust)\nfn has_selector(module: &[u8], selector: &[u8]) -> bool {\n    let mut pattern = vec![0x63u8]; // PUSH4\n    pattern.extend_from_slice(selector);\n    module.windows(5).any(|w| w == pattern)\n}\n\nlet required: &[(&[u8], &str)] = &[\n    (EXECUTE_MESSAGE_SELECTOR, \"execute_message\"),\n    (PROCESS_STREAMS_SELECTOR, \"process_streams\"),\n    (SUMMARIZE_EVENTS_SELECTOR, \"summarize_events\"),\n];\nfor (sel, name) in required {\n    assert!(has_selector(&contract_bytecode, sel), \"missing {name} in bytecode\");\n}\npublish(contract_bytecode)?;","typeGuard":"fn is_missing_function(err: &ExecutionError) -> Option<&str> {\n    match err {\n        ExecutionError::EvmError(EvmExecutionError::MissingFunction(name)) => Some(name),\n        _ => None,\n    }\n}","tryCatchPattern":"match runtime.receive_message(msg).await {\n    Ok(()) => {}\n    Err(ref e) if is_missing_function(e).is_some() => {\n        log::warn!(\"bytecode lacks {:?}; redeploy with the base contract\", is_missing_function(e));\n        return Err(e.clone()); // deterministic failure: do not retry\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["evm","solidity","bytecode","missing-function","linera"],"backgroundTag":"missing-contract-function","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}