BoundaryML/baml · error · Error

Video is not base64

Error message

Video is not base64

What it means

Video.asBase64() throws this when the video's content is stored as a URL rather than base64 data. The accessor only returns [base64Data, mediaType] for the base64 representation, so it defensively throws when this.type is not "base64". Check isUrl()/the type field before calling it.

Source

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

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

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

  /**
   * Convert the video 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 video.type (or isUrl()) before calling asBase64() and fall back to asUrl() otherwise
  2. Fetch the URL content and convert it to base64 with the correct media type before calling base64-based APIs
  3. Construct the Video with base64 content if your downstream pipeline requires it
  4. Normalize all videos through a converter function that handles both representations

Example fix

// before
const [data, mediaType] = video.asBase64();
// after
if (video.isUrl()) {
  const res = await fetch(video.asUrl());
  const buf = Buffer.from(await res.arrayBuffer());
  var [data, mediaType] = [buf.toString("base64"), res.headers.get("content-type") ?? ""];
} else {
  [data, mediaType] = video.asBase64();
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (video.type !== "base64") {
  // fetch the URL and convert to base64 first
}

Type guard

function isBase64Video(v) { return typeof v.type === "string" && v.type === "base64"; }

Try / catch

let data, mediaType;
try {
  [data, mediaType] = video.asBase64();
} catch (e) {
  if (e.message === "Video is not base64") {
    ({ data, mediaType } = await convertUrlToBase64(video.asUrl()));
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling video.asBase64() on a Video constructed from a URL (this.type !== "base64"), e.g. Video.fromUrl("https://...") content being piped into a code path that expects inline base64 media.

Common situations: Preparing multimodal requests for APIs that require base64 media while the source video was given as a URL; switching between local testing (URLs) and production (base64) media sources; assuming a uniform representation across Video instances deserialized from mixed inputs.

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/5003c015f99c88ff. Report an issue: GitHub.