facebook/flow · critical

Can't decode daemon parameters: {}

Error message

Can't decode daemon parameters: {}

What it means

When a flow daemon child starts, Daemon::get_context reads the parameter file the parent wrote and bincode-decodes a Context with the legacy config. The earlier arm already panicked if the file was missing; this panic means the file existed but its bytes failed to decode: a truncated/partially-flushed write, or a format/version mismatch between the flow build that wrote the file and the daemon binary decoding it.

Source

Thrown at rust_port/crates/flow_daemon/src/daemon.rs:292

    // I'm not entirely sure what this does on Windows.
    pub(crate) fn get_context() -> Option<(String, Context)> {
        let entry = std::env::var(ENV_DAEMON).ok().filter(|s| !s.is_empty())?;
        let file = std::env::var(ENV_DAEMON_PARAM)
            .ok()
            .filter(|s| !s.is_empty())?;
        let bytes =
            fs::read(&file).unwrap_or_else(|e| panic!("Can't find daemon parameters: {}", e));
        if let Err(e) = fs::remove_file(&file) {
            tracing::warn!(
                target: "flow_daemon",
                "Daemon::get_context: failed to remove param file {:?}: {}",
                file,
                e
            );
        }
        let (context, _): (Context, usize) =
            bincode::serde::decode_from_slice(&bytes, bincode::config::legacy())
                .unwrap_or_else(|e| panic!("Can't decode daemon parameters: {}", e));
        Some((entry, context))
    }

    // No-op in Rust: we never mutate the parent's env (we set per-child env
    // via `Command::env`), so there's nothing to clear. Kept as a function
    // for OCaml structural fidelity.
    pub(crate) fn clear_context() {}
}

pub use entry::Entry;

fn exec(entry: &str, in_sock: TcpStream, out_sock: TcpStream, param_bytes: Vec<u8>) -> ! {
    let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
        entry::find_and_call(entry, param_bytes, in_sock, out_sock);
    }));
    match result {
        Ok(()) => std::process::exit(0),
        Err(e) => {

View on GitHub (pinned to f88ac94bcf)

Solutions

  1. Run flow stop (or kill leftover daemons) and retry so a fresh param file is written by the current build
  2. Ensure exactly one flow version is reachable (one install on PATH, no stale copies)
  3. Clear flow's temp/socket directory entries after upgrades
  4. Free disk space if the volume was full when the file was written

Example fix

# before
flow check   # daemon child panics: Can't decode daemon parameters: <e>

# after
flow stop
rm -rf "$TMPDIR"/flow* 2>/dev/null
flow check
Defensive patterns

Strategy: retry

Prevention

When it happens

Trigger: Two different flow versions interleaved (one install's client spawns a daemon from another install); the param file corrupted by a full disk during write; a leftover param file from an older daemon format being read by a newer build.

Common situations: Upgrading flow while daemons and socket/temp dirs persist; multiple flow installs on PATH; CI images reusing a polluted temp dir; disk-full events corrupting flow's temp files.

Related errors


AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20). Data as JSON: /api/errors/4726d82f4325c959. Report an issue: GitHub.