zeroclaw-labs/zeroclaw · error

Flash failed:\n{}\n\nEnsure Nucleo is connected via USB. The

Error message

Flash failed:\n{}\n\nEnsure Nucleo is connected via USB. The ST-Link is built into the board.

What it means

The final step of flash_nucleo_firmware runs `probe-rs run --chip STM32F401RETx <elf>` and bails with probe-rs's stderr plus a USB/ST-Link hint on non-zero exit. probe-rs is installed and the firmware built; the debug session to the board itself failed.

Source

Thrown at crates/zeroclaw-hardware/src/peripherals/nucleo_flash.rs:79

            "Built binary not found at {}",
            elf_path.display().to_string()
        );
    }

    println!("Flashing to Nucleo-F401RE (connect via USB)...");
    let flash = Command::new("probe-rs")
        .args([
            "run",
            "--chip",
            CHIP,
            elf_path.to_str().context("ELF path is not valid UTF-8")?,
        ])
        .output()
        .context("probe-rs run failed")?;

    if !flash.status.success() {
        let stderr = String::from_utf8_lossy(&flash.stderr);
        anyhow::bail!(
            "Flash failed:\n{}\n\n\
             Ensure Nucleo is connected via USB. The ST-Link is built into the board.",
            stderr
        );
    }

    println!("ZeroClaw Nucleo firmware flashed successfully.");
    println!("The Nucleo now supports: ping, capabilities, gpio_read, gpio_write.");
    println!(
        "Add to config.toml: board = \"nucleo-f401re\", transport = \"serial\", path = \"/dev/ttyACM0\""
    );
    Ok(())
}

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Run `probe-rs list` — if no probe appears, fix cable/port/power (use a data-capable USB cable)
  2. Close every other ST-Link session (STM32CubeIDE, openocd, another probe-rs) and retry
  3. On Linux, install the probe-rs udev rules and re-plug the board
  4. Read the embedded stderr: 'unable to open probe' points at USB/permissions, 'no target found' at the chip connection
Defensive patterns

Strategy: retry

Validate before calling

let probes = std::process::Command::new("probe-rs")
    .arg("list")
    .output()?;
if String::from_utf8_lossy(&probes.stdout).trim().is_empty() {
    anyhow::bail!("no debug probe visible; fix USB cable/port before flashing");
}
flash_nucleo_firmware()?;

Try / catch

match flash_nucleo_firmware() {
    Err(e) if format!("{e}").contains("Flash failed") => {
        // ask user to reconnect the Nucleo / free the ST-Link, wait, retry once
    }
    rest => rest,
}

Prevention

When it happens

Trigger: Nucleo not connected or connected with a power-only USB cable; the ST-Link is already claimed by another session (STM32CubeIDE, openocd, second probe-rs); Linux udev rules for ST-Link missing so the probe cannot be opened; the target held in a bad state by previous firmware.

Common situations: An IDE or other debugger holding the ST-Link; fresh Linux installs without probe-rs udev rules; charging cables without data lines; boards stuck in low-power mode.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/34edec3f7cb25d7b. Report an issue: GitHub.