QuipNetwork/hashsigs-rs · warning · Error

[{err.code}] {err.message}

Error message

[{err.code}] {err.message}

What it means

This is the fallback message format `[CODE] message` produced by js_error in src/wasm/mod.rs when js_sys::Reflect::set fails to attach the `code` property to the JS Error object. The library folds the machine-readable code into the message string so the code is never lost, at the cost of a non-standard message shape.

Solutions

  1. Parse the code out of the message with /^\[(.+?)\] / when e.code is undefined.
  2. Prefer matching on the code (from e.code or the parsed prefix) rather than the full message string.
  3. Verify the JS runtime allows defining properties on Error instances; test Reflect behavior if embedding in a custom host.
  4. Report/upgrade if your host makes Reflect::set fail, since it degrades the API surface.

Example fix

// before
if (e.message === "invalid public key") { ... }
// after
const m = /^\[(.+?)\] /.exec(e.message);
const code = e.code ?? m?.[1];
if (code === "INVALID_PUBLIC_KEY") { ... }
Defensive patterns

Strategy: fallback

Validate before calling

function extractWasmCode(e) {
  if (typeof e?.code === 'string') return e.code;
  const m = /^\[(.+?)\] /.exec(e?.message ?? '');
  return m ? m[1] : null;
}

Type guard

function hasFoldedCode(e) {
  return e instanceof Error && e.code === undefined && /^\[.+?\] /.test(e.message);
}

Try / catch

try {
  wasmApi(input);
} catch (e) {
  const code = extractWasmCode(e); // works for both property and folded message
  if (code === null) throw e;
  dispatchByCode(code, e.message.replace(/^\[.+?\] /, ''));
}

Prevention

When it happens

Trigger: A WasmErr crosses the wasm->JS boundary while Reflect::set on the Error object returns an error (e.g. exotic JS hosts/proxies where the Error object rejects new property definitions); the returned Error's message becomes "[code] err.message" instead of plain err.message.

Common situations: Running the wasm module in hardened or sandboxed JS environments (frozen objects, unusual realms) where property definition on Error instances fails; code that matches on exact message text breaks because messages now carry a `[CODE] ` prefix; tooling that relies on e.code gets undefined.

Related errors


AI-assisted analysis of QuipNetwork/hashsigs-rs@128c4ccb5c (2026-09-08). Data as JSON: /api/errors/b130c8b1287a4a57. Report an issue: GitHub.

Appendix: source

Thrown at src/wasm/mod.rs:1684

}

#[cfg(any(test, feature = "wasm-bindings"))]
fn hex_string(bytes: &[u8]) -> String {
    let mut out = String::from("0x");
    for byte in bytes {
        use core::fmt::Write;
        let _ = write!(out, "{byte:02x}");
    }
    out
}

#[cfg(feature = "wasm-bindings")]
fn js_error(err: WasmErr) -> JsValue {
    let e = js_sys::Error::new(&err.message);
    if js_sys::Reflect::set(&e, &JsValue::from_str("code"), &JsValue::from_str(err.code)).is_err() {
        // Reflect::set failed, so the machine-readable code would be lost off the
        // Error object. Fold it into the message so callers never lose it.
        return js_sys::Error::new(&format!("[{}] {}", err.code, err.message)).into();
    }
    e.into()
}

/// Build a serde-boundary error handler tagged with a STATIC argument label
/// (e.g. `"publicKey"`). The label identifies which argument failed to
/// deserialize without ever echoing the caller-supplied value (inputs include
/// secret seeds). Returns a closure so call sites read
/// `.map_err(js_error_from_serde("publicKey"))`.
#[cfg(feature = "wasm-bindings")]
fn js_error_from_serde(label: &'static str) -> impl Fn(serde_wasm_bindgen::Error) -> JsValue {
    move |_error| {
        js_error(WasmErr {
            code: ERR_INVALID_INPUT,
            message: format!("invalid {label}: argument shape or field encoding"),
        })
    }
}

View on GitHub (pinned to 128c4ccb5c)