BoundaryML/baml · error · Error

Audio is not base64

Error message

Audio is not base64

What it means

BAML's Audio.asBase64() only works when the audio content is stored as base64. If the audio was created from a URL, there is no inline base64 payload, so the method throws instead of returning meaningless data.

Source

Thrown at engine/language_client_typescript/typescript_src/audio.ts:81

  /**
   * Get the URL of the audio if it's stored as a URL
   * @throws Error if the audio is not stored as a URL
   */
  asUrl(): string {
    if (!this.isUrl()) {
      throw new Error('Audio is not a URL');
    }
    return this.content;
  }

  /**
   * Get the base64 data and media type if the audio is stored as base64
   * @returns [base64Data, mediaType]
   * @throws Error if the audio is not stored as base64
   */
  asBase64(): [string, string] {
    if (this.type !== 'base64') {
      throw new Error('Audio is not base64');
    }
    return [this.content, this.mediaType || ''];
  }

  /**
   * Convert the audio to a JSON representation
   */
  toJSON(): { url: string } | { base64: string; media_type: string } {
    if (this.type === 'url') {
      return { url: this.content };
    }
    return {
      base64: this.content,
      media_type: this.mediaType || '',
    };
  }
}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Check audio.type === 'base64' (or use the accessor for URLs) before calling asBase64()
  2. Download/fetch the audio from the URL yourself and encode it to base64 if you need bytes
  3. Ensure the Audio was created via Audio.fromBase64(...) when base64 access is required

Example fix

// before
const [b64, mt] = audio.asBase64(); // throws for URL audio
// after
if (audio.type === 'base64') {
  const [b64, mt] = audio.asBase64();
} else {
  const res = await fetch(audio.asUrl());
  const b64 = Buffer.from(await res.arrayBuffer()).toString('base64');
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (audio.type !== 'base64') { /* fetch URL and encode */ }

Type guard

const isBase64Audio = (a) => a.type === 'base64';

Try / catch

try { const [b64, mt] = audio.asBase64(); }
catch { const bytes = await (await fetch(audio.asUrl())).arrayBuffer(); }

Prevention

When it happens

Trigger: Calling audio.asBase64() on an Audio whose storage type is 'url' (constructed via fromUrl), i.e. this.type !== 'base64'.

Common situations: Code paths that expect embedded media (e.g. to write bytes to disk or inline into a request) but received URL-referenced audio from a response or config; switching media sources without updating downstream consumers.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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