BoundaryML/baml · error · JwtError
Missing crypto API
Error message
Missing crypto API
What it means
JwtError::NoCrypto is returned when the window exists but the WebCrypto API (window.crypto or crypto.subtle) is unavailable. SubtleCrypto is required for signing JWTs and is only exposed in secure contexts.
Solutions
- Serve the application over HTTPS (or http://localhost, which is a secure context).
- Check window.crypto?.subtle at startup and show a clear feature-unsupported message.
- Upgrade to a browser that implements the Web Crypto API.
- If stuck on http, proxy through a TLS-terminating server for development.
Example fix
// before let crypto = window.crypto().unwrap(); // after let crypto = window.crypto().ok_or(JwtError::NoCrypto)?; let subtle = crypto.subtle().ok_or(JwtError::NoCrypto)?;
Defensive patterns
Strategy: validation
Validate before calling
if (!window.isSecureContext || !window.crypto?.subtle) {
throw new Error("NoCrypto: WebCrypto requires a secure context (HTTPS)");
} Type guard
function cryptoAvailable(w) {
return !!w.crypto && !!w.crypto.subtle;
} Try / catch
try {
const key = await importKey(rawKey);
} catch (e) {
if (!window.crypto?.subtle) showHttpsWarning();
else throw e;
} Prevention
- Serve all pages over HTTPS or localhost.
- Feature-detect crypto.subtle at app startup and degrade gracefully.
- Check embedded WebView crypto support before enabling JWT features.
When it happens
Trigger: Accessing window.crypto.subtle on a page served over plain http:// (insecure origin); very old browsers lacking WebCrypto; embedded webviews with crypto disabled.
Common situations: Local development served over http on non-localhost hosts (e.g. LAN IP); testing in an embedded WebView; corporate browser policies disabling crypto.subtle.
Related errors
- JavaScript error
- Base64 decode error
- JSON error
- Missing window object
- BAML internal error - credential provider bridges not…
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/5282433a8372f39f.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-runtime/src/internal/wasm_jwt.rs:33
use js_sys::{Array, Object, Uint8Array};
use serde::{Deserialize, Serialize};
use serde_json::json;
use thiserror::Error;
use wasm_bindgen::JsValue;
use wasm_bindgen_futures::JsFuture;
use web_sys::{window, CryptoKey, SubtleCrypto};
#[derive(Error, Debug)]
pub enum JwtError {
#[error("JavaScript error: {0:?}")]
JsError(JsValue),
#[error("Base64 decode error: {0}")]
Base64Error(#[from] base64::DecodeError),
#[error("JSON error: {0}")]
JsonError(#[from] serde_json::Error),
#[error("Missing window object")]
NoWindow,
#[error("Missing crypto API")]
NoCrypto,
}
impl From<JsValue> for JwtError {
fn from(err: JsValue) -> Self {
JwtError::JsError(err)
}
}
pub async fn encode_jwt(
claims: &serde_json::Value,
private_key_pem: &str,
) -> Result<String, JwtError> {
// Extract the crypto.subtle API
let window = window().ok_or(JwtError::NoWindow)?;
let crypto = window.crypto()?;
let subtle = crypto.subtle();
View on GitHub (pinned to bd85ce9dee)