{"record":{"id":"1f70433be2b76555","repo":"BoundaryML/baml","slug":"audio-is-not-a-url-1f7043","errorCode":null,"errorMessage":"Audio is not a URL","messagePattern":"Audio is not a URL","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"engine/language_client_typescript/typescript_src/audio.ts","lineNumber":69,"sourceCode":"    const response = await fetch(url);\n    const blob = await response.blob();\n    return BamlAudio.fromBlob(blob);\n  }\n\n  /**\n   * Check if the audio is stored as a URL\n   */\n  isUrl(): boolean {\n    return this.type === 'url';\n  }\n\n  /**\n   * Get the URL of the audio if it's stored as a URL\n   * @throws Error if the audio is not stored as a URL\n   */\n  asUrl(): string {\n    if (!this.isUrl()) {\n      throw new Error('Audio is not a URL');\n    }\n    return this.content;\n  }\n\n  /**\n   * Get the base64 data and media type if the audio is stored as base64\n   * @returns [base64Data, mediaType]\n   * @throws Error if the audio is not stored as base64\n   */\n  asBase64(): [string, string] {\n    if (this.type !== 'base64') {\n      throw new Error('Audio is not base64');\n    }\n    return [this.content, this.mediaType || ''];\n  }\n\n  /**\n   * Convert the audio to a JSON representation","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_typescript/typescript_src/audio.ts#L51-L87","documentation":"BAML's Audio media object can hold content either as a URL or as base64 data. asUrl() is a narrowing accessor that returns the content only when the audio was constructed from a URL; otherwise it throws to prevent silently returning base64 data as if it were a URL.","triggerScenarios":"Calling audio.asUrl() on an Audio created with fromBase64 (or from any non-URL source such as a file/raw media), where isUrl() is false.","commonSituations":"Receiving Audio objects from a BAML client/LLM response and assuming they are always URL-backed; mixing base64-embedded media (common when passing raw bytes to models) with URL-based media handling code.","solutions":["Check audio.isUrl() before calling asUrl(), and branch to asBase64() otherwise","Construct the Audio from a URL (Audio.fromUrl(...)) when URL access is required","Write generic handling that inspects the storage type instead of assuming one"],"exampleFix":"// before\nconst url = audio.asUrl(); // throws for base64 audio\n// after\nif (audio.isUrl()) {\n  const url = audio.asUrl();\n} else {\n  const [b64, mediaType] = audio.asBase64();\n}","handlingStrategy":"type-guard","validationCode":"if (!audio.isUrl()) { /* handle base64 branch */ }","typeGuard":"const isUrlAudio = (a) => a.isUrl();","tryCatchPattern":"try { const url = audio.asUrl(); }\ncatch { const [b64, mt] = audio.asBase64(); /* fallback path */ }","preventionTips":["Always check isUrl() before asUrl()","Decide URL vs base64 handling at the media-construction site","Centralize media access in a helper that branches on storage type"],"tags":["audio","media","base64","url"],"backgroundTag":"incompatible-source-type","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}