BoundaryML/baml · error · Error
Video is not a URL
Error message
Video is not a URL
What it means
Video.asUrl() throws this when the video's content is stored as base64 data rather than as a URL. The class supports two storage representations (URL and base64) and asUrl is only valid for the URL representation. Callers must check isUrl() or use the matching accessor first.
Source
Thrown at engine/language_client_typescript/typescript_src/video.ts:69
const response = await fetch(url);
const blob = await response.blob();
return BamlVideo.fromBlob(blob);
}
/**
* Check if the video is stored as a URL
*/
isUrl(): boolean {
return this.type === "url";
}
/**
* 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 representationView on GitHub (pinned to bd85ce9dee)
Solutions
- Check video.isUrl() before calling asUrl() and branch to asBase64() for base64 content
- Convert the base64 content to a data URI instead of using asUrl()
- Pass the video as a URL when constructing it so the URL accessor is valid
- Inspect the deserialization path to ensure the content type flag survives round-trips
Example fix
// before
const url = video.asUrl();
// after
const url = video.isUrl() ? video.asUrl() : `data:${video.asBase64()[1]};base64,${video.asBase64()[0]}`; Defensive patterns
Strategy: type-guard
Validate before calling
if (!video.isUrl()) {
// take the asBase64() path instead
} Type guard
function isUrlVideo(v) { return typeof v.isUrl === "function" && v.isUrl(); } Try / catch
let url;
try {
url = video.asUrl();
} catch (e) {
if (e.message === "Video is not a URL") {
url = null; // handle base64 case via asBase64()
} else {
throw e;
}
} Prevention
- Always branch on isUrl() before choosing an accessor
- Keep the storage representation explicit in your media pipeline (tag videos as 'url' or 'base64')
- Add a converter utility that normalizes both representations before consumption
When it happens
Trigger: Calling video.asUrl() on a Video constructed with base64 content (e.g. Video.fromBase64 or media built from raw bytes) instead of URL content. Equivalently, calling asUrl() when video.isUrl() returns false.
Common situations: Passing inline base64-encoded videos (common in LLM multimodal prompts) to code that assumes all videos are URL-backed; deserializing videos from JSON where the content type was lost; rendering code that blindly calls asUrl() without branching on the storage type.
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
- Video is not base64
- Video is not a URL
- Video is not base64
- Video input is not yet supported by Anthropic Claude models.
- not yet implemented
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/ae3e6be2cf76f27c.
Report an issue: GitHub.