emilk/egui · warning
ERROR: {msg}
Error message
ERROR: {msg} What it means
eframe's web logger routes log::Level::Error records to console.warn(format!("ERROR: {msg}")) instead of console.error, because calling console.error crashed browsers (see egui PR #2961). So a JavaScript console line reading "ERROR: ..." is a warning-level console message produced by this fallback — the actual failure is whatever msg contains; the library deliberately downgrades the severity to avoid the crash.
Source
Thrown at crates/eframe/src/web/web_logger.rs:65
let msg = if let (Some(file), Some(line)) = (record.file(), record.line()) {
let file = shorten_file_path(file);
format!("[{}] {file}:{line}: {}", record.target(), record.args())
} else {
format!("[{}] {}", record.target(), record.args())
};
match record.level() {
// NOTE: the `console::trace` includes a stack trace, which is super-noisy.
log::Level::Trace => console::debug(&msg),
log::Level::Debug => console::debug(&msg),
log::Level::Info => console::info(&msg),
log::Level::Warn => console::warn(&msg),
// Using console.error causes crashes for unknown reason
// https://github.com/emilk/egui/pull/2961
// log::Level::Error => console::error(&msg),
log::Level::Error => console::warn(&format!("ERROR: {msg}")),
}
}
fn flush(&self) {}
}
/// js-bindings for console.log, console.warn, etc
mod console {
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
/// `console.trace`
#[wasm_bindgen(js_namespace = console)]
pub fn trace(s: &str);
/// `console.debug`
#[wasm_bindgen(js_namespace = console)]View on GitHub (pinned to 441971a776)
Solutions
- Treat console lines with the "ERROR: " prefix as real errors when triaging wasm app logs
- Find and fix the root cause reported in msg — the prefix line itself is only the transport
- Install a custom log implementation (log::set_boxed_logger) if you need console.error or structured error reporting (e.g. forwarding to Sentry)
- Check for an updated eframe where the console.error crash (PR #2961) is fixed and the workaround removed
Defensive patterns
Strategy: try-catch
Try / catch
// Intercept error-level logs in wasm before the default web logger:
struct SentryLogger;
impl log::Log for SentryLogger {
fn enabled(&self, m: &log::Metadata) -> bool { m.level() <= log::Level::Trace }
fn log(&self, r: &log::Record) {
if r.level() == log::Level::Error { send_to_sentry(&format!("{}", r.args())); }
else { console::log_1(&format!("{}", r.args()).into()); }
}
fn flush(&self) {}
}
let _ = log::set_boxed_logger(Box::new(SentryLogger)); Prevention
- Filter browser consoles on the "ERROR: " prefix, not console.error, when triaging eframe wasm apps
- Install a custom log implementation if you need real console.error or error-tracking integration
- Fix the root cause in msg — the prefixed warn line is only the transport, not the bug
- Track egui releases for removal of the console.error crash workaround (PR #2961)
When it happens
Trigger: Any log::error!(...) (or an error-level log from a dependency) executed inside an eframe web/wasm app while this logger is installed — the message is emitted via console.warn with the "ERROR: " prefix rather than console.error.
Common situations: Debugging a wasm eframe app whose console shows ERROR: lines without matching JS error objects (breakpoints on console.error never fire); confusion in error monitoring that filters on console.error and therefore misses these; hitting the original console.error browser crash on older toolchains.
Related errors
- Your app must implement `as_any_mut`, but it doesn't
- should have a Window
- should have a Performance
- Single-use AppCreator has unexpectedly already been taken
- failed to fit multisamples option of native_options into u8
AI-assisted analysis of emilk/egui@441971a776 (2026-09-12).
Data as JSON: /api/errors/b175660799ef42fe.
Report an issue: GitHub.