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.
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)
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: {0:?}
- Base64 decode error: {0}
- JSON error: {0}
- Missing window object
- WASM history boundary {} was not begun
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/5282433a8372f39f.
Report an issue: GitHub.