iced-rs/iced · error
Encode input message
Error message
Encode input message
What it means
In iced's beacon debug bridge (the client an instrumented app uses to talk to the iced debug UI), `send` frames messages by bincode-serializing a `client::Message` and treating encoder failure as fatal via `.expect("Encode input message")`. bincode's `serialize` only returns Err when the value's `Serialize` impl itself errors, so this is a protocol-invariant assertion, not a network error path.
Source
Thrown at beacon/src/client.rs:238
/// Otherwise, a default local server address will be returned.
pub fn server_address_from_env() -> String {
const DEFAULT_ADDRESS: &str = "127.0.0.1:9167";
std::env::var("ICED_BEACON_SERVER_ADDRESS").unwrap_or_else(|_| String::from(DEFAULT_ADDRESS))
}
async fn _connect() -> Result<net::TcpStream, io::Error> {
log::debug!("Attempting to connect to server...");
let stream = net::TcpStream::connect(server_address_from_env()).await?;
stream.set_nodelay(true)?;
stream.writable().await?;
Ok(stream)
}
async fn send(stream: &mut net::tcp::OwnedWriteHalf, message: Message) -> Result<(), io::Error> {
let bytes = bincode::serialize(&message).expect("Encode input message");
let size = bytes.len() as u64;
stream.write_all(&size.to_be_bytes()).await?;
stream.write_all(&bytes).await?;
stream.flush().await?;
Ok(())
}
async fn receive(
stream: &mut net::tcp::OwnedReadHalf,
buffer: &mut Vec<u8>,
) -> Result<Command, Error> {
let size = stream.read_u64().await? as usize;
if buffer.len() < size {
buffer.resize(size, 0);
}View on GitHub (pinned to 2cffa99b39)
Solutions
- Fix the Message payload type so bincode can encode it (proper derived Serialize/Deserialize, no fallible serializer behavior)
- Replace `.expect(...)` with `?` mapped into io::Error so a bad frame closes the connection instead of killing the app
- Add a serialize+deserialize round-trip unit test covering every protocol variant
- Unset ICED_BEACON_SERVER_ADDRESS or disable the debug feature to switch the bridge off while investigating
Example fix
// before
let bytes = bincode::serialize(&message).expect("Encode input message");
// after
let bytes = bincode::serialize(&message)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; Defensive patterns
Strategy: validation
Validate before calling
#[test]
fn beacon_message_roundtrip() {
for msg in all_message_variants() { // helper enumerating every client::Message
let bytes = bincode::serialize(&msg).expect("serialize");
let _back: Message = bincode::deserialize(&bytes).expect("deserialize");
}
} Prevention
- Keep the beacon protocol types' Serialize/Deserialize derived and covered by a round-trip test
- Build the app and the iced debug UI from the same iced version so wire types match
- Unset ICED_BEACON_SERVER_ADDRESS or disable the debug feature in release builds
- Treat any payload added to Message/Command without derived serde as a breaking protocol change
When it happens
Trigger: Any debug event sent after the beacon client connects (theme change, span finished, tasks spawned, subscriptions tracked, ...) goes through `send`. The panic fires only when serialization of that specific `Message` variant fails at runtime, e.g. a payload added to the protocol whose Serialize impl errors (skipped/malformed fields, invalid enum encoding).
Common situations: Extending iced's debug protocol with a new message variant that is not cleanly bincode-serializable; mixing an app built against one iced version with a beacon/debug UI built from another so the wire types differ; running with ICED_BEACON_SERVER_ADDRESS set during development.
Related errors
- Encode input message
- Read application metadata
- Write application metadata
- Read last palette
- Write last palette
AI-assisted analysis of iced-rs/iced@2cffa99b39 (2026-08-16).
Data as JSON: /api/errors/cfabc727845531a3.
Report an issue: GitHub.