linera-io/linera-protocol · error · std::io::Error
failed to load contract bytecode from {contract:?}: {e}
Error message
failed to load contract bytecode from {contract:?}: {e} What it means
ClientContext::publish_module loads the contract half of an application from the --contract path using Bytecode::load_from_file, re-wrapping any I/O failure with the specific contract path. This is the contract-side twin of the service error at line 860; which one fires tells you which path argument was bad. The error is a plain I/O condition (kind preserved), not a Wasm-validation failure.
Source
Thrown at linera-client/src/client_context.rs:854
chain_info,
})
}
}
#[cfg(feature = "fs")]
impl<Env: Environment> ClientContext<Env> {
/// Publishes a module from its contract and service bytecode files.
pub async fn publish_module(
&mut self,
chain_client: &ChainClient<Env>,
contract: PathBuf,
service: PathBuf,
vm_runtime: VmRuntime,
formats: Option<PathBuf>,
) -> Result<ModuleId, Error> {
info!("Loading bytecode files");
let contract_bytecode = Bytecode::load_from_file(&contract).await.map_err(|e| {
std::io::Error::new(
e.kind(),
format!("failed to load contract bytecode from {contract:?}: {e}"),
)
})?;
let service_bytecode = Bytecode::load_from_file(&service).await.map_err(|e| {
std::io::Error::new(
e.kind(),
format!("failed to load service bytecode from {service:?}: {e}"),
)
})?;
let formats_bytes = match formats {
Some(path) => Some(bcs::to_bytes(&load_formats_from_snap(&path)?)?),
None => None,
};
info!("Publishing module");
let (blobs, module_id) = create_bytecode_blobs(View on GitHub (pinned to 6c226ddcb3)
Solutions
- Check the exact --contract path exists and is a file (`ls -l`); if missing, build the wasm32 artifacts and reuse the path printed by the build step.
- Use the artifact from target/wasm32-unknown-unknown/release/, not target/release/, and prefer absolute paths (or run the CLI from the project root) to avoid cwd-relative misses.
- If it exists but still fails, fix permissions/ownership or mount the artifact directory into the container/CI environment.
Example fix
# before linera publish-module --contract contract.wasm --service service.wasm ... # fails if run from a dir without those files # after: build first, publish with the real wasm32 target paths linera publish-module \ --contract target/wasm32-unknown-unknown/release/my_app_contract.wasm \ --service target/wasm32-unknown-unknown/release/my_app_service.wasm ...
Defensive patterns
Strategy: try-catch
Validate before calling
fn artifacts_exist(paths: &[&std::path::Path]) -> anyhow::Result<()> {
for p in paths {
let meta = std::fs::metadata(p)
.with_context(|| format!("missing artifact {}; run the wasm32 build first", p.display()))?;
anyhow::ensure!(meta.is_file(), "{} is not a file", p.display());
}
Ok(())
} Try / catch
if let Err(e) = context.publish_module(chain_client.clone(), contract, service, vm_runtime, formats).await {
if e.to_string().contains("failed to load contract bytecode") {
eprintln!("contract wasm missing — run: cargo build --target wasm32-unknown-unknown --release");
}
return Err(e);
} Prevention
- Gate the publish command on an artifacts-exists check for both wasm paths.
- Use build scripts (linera build / cargo workspace invocations) that emit the artifact paths and feed them to publish verbatim.
- Treat any target/release/*.wasm absence as a signal you built native-only; always build with --target wasm32-unknown-unknown.
When it happens
Trigger: Calling publish_module (the `linera publish-module --contract <path> --service <path>` flow) where the --contract path is missing, unreadable, a directory, or a dangling symlink. It fires before the service path is read or any chain communication starts.
Common situations: Publishing before `cargo build --target wasm32-unknown-unknown --release` (or `linera build`) produced the contract .wasm; pointing --contract at the native target dir; a typo in the filename; running from the wrong working directory with a relative path; CI artifacts not copied into the job's container.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- failed to load service bytecode from {service:?}: {e}
- {}: {error}
- failed to load data blob bytes from {blob_path:?}: {e}
- failed to read SNAP file {path:?}: {e}
- Unable to read validator options file
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/ce51f6cfdb207726.
Report an issue: GitHub.