diff --git a/core/archipelago/src/api/rpc/middleware.rs b/core/archipelago/src/api/rpc/middleware.rs index bba77598..0b6c093e 100644 --- a/core/archipelago/src/api/rpc/middleware.rs +++ b/core/archipelago/src/api/rpc/middleware.rs @@ -84,6 +84,33 @@ pub(super) fn sanitize_error_message(msg: &str) -> String { // Masking sent the operator to journalctl again (framework-pt // sweep, 2026-08-06) — same lesson as the two above. "Failed to send", + // A frontend newer than the daemon calls methods it doesn't have. + // Masked, this reads as "the feature is broken" instead of "this + // node needs its update" — hit live the moment the .126 LoRa panel + // was deployed ahead of its binary (2026-08-06). + "Unknown method", + // RNode RF settings validation (mesh::rnode_settings::validate) — + // every one names the offending field and its legal range, which is + // the entire point of validating before touching the radio. + "frequency ", + "bandwidth ", + "spreading factor ", + "coding rate ", + "tx power ", + "airtime_limit_short", + "airtime_limit_long", + "port must be an absolute", + "Invalid settings", + "Missing 'settings'", + // Mesh preconditions the operator can act on directly. + "Mesh service not running", + "No mesh device connected", + "Mesh listener not running", + "MeshCore radios have no remote reboot", + "Radio state read-back", + "The radio daemon did not answer", + "The radio did not acknowledge", + "RNode interface is disabled", // Lightning payment failures carry LND's reason ("invoice expired. // Valid until …", "no route", …) — the user can act on every one of // them, and masking sent the operator to journalctl (invoice-expired