BoundaryML/baml · error · JwtError

Base64 decode error: {0}

Error message

Base64 decode error: {0}

What it means

JwtError::Base64Error converts a base64::DecodeError (via #[from]) when decoding base64 material — typically the JWT header/payload segments or key data — fails because the input is not valid base64. Raised while parsing parts of a JWT inside the wasm JWT helper.

Source

Thrown at engine/baml-runtime/src/internal/wasm_jwt.rs:27

/// At the time of writing, the Vertex provider is the only code in the
/// runtime that produces JWT's.
use base64::{
    engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD},
    Engine,
};
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,

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Validate the token has three dot-separated base64url segments before decoding.
  2. Use a base64url decoder configuration (URL_SAFE_NO_PAD) matching JWT encoding.
  3. Trim whitespace and newlines from the token string before decoding.
  4. Check where the token comes from — an error response body may be what's being decoded.

Example fix

// before
base64::decode(segment)?
// after
base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(segment.trim())?
Defensive patterns

Strategy: validation

Validate before calling

const isJwtShape = (t) => /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$/.test(t.trim());
if (!isJwtShape(token)) throw new Error("Not a valid JWT shape");

Type guard

function isJwt(value) {
  return typeof value === "string" && value.trim().split(".").length === 3;
}

Try / catch

match decode_token(token) {
    Ok(decoded) => Ok(decoded),
    Err(JwtError::Base64Error(e)) => {
        eprintln!("Token is not valid base64url: {}", e);
        Err(JwtError::Base64Error(e))
    }
    Err(other) => Err(other),
}

Prevention

When it happens

Trigger: Passing a malformed or truncated JWT string to the decoder; base64url segments containing illegal characters; a key or token fetched from an API that is not actually base64.

Common situations: Copy-pasted JWT with missing padding or whitespace/newlines; error HTML/JSON response stored in the token variable; manually trimmed token cut mid-segment; confusing base64url with standard base64.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/60c0761d6e0ba428. Report an issue: GitHub.