{"record":{"id":"c791ebda166a94d4","repo":"BoundaryML/baml","slug":"audio-is-not-a-url","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/audio.js","lineNumber":68,"sourceCode":"     */\n    static async fromUrlAsync(url) {\n        const response = await fetch(url);\n        const blob = await response.blob();\n        return BamlAudio.fromBlob(blob);\n    }\n    /**\n     * Check if the audio is stored as a URL\n     */\n    isUrl() {\n        return this.type === 'url';\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() {\n        if (!this.isUrl()) {\n            throw new Error('Audio is not a URL');\n        }\n        return this.content;\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() {\n        if (this.type !== 'base64') {\n            throw new Error('Audio is not base64');\n        }\n        return [this.content, this.mediaType || ''];\n    }\n    /**\n     * Convert the audio to a JSON representation\n     */\n    toJSON() {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_typescript/audio.js#L50-L86","documentation":"The TypeScript Audio Media wrapper stores content either as a URL or as base64 data. asUrl() is an accessor that is only valid when the audio was constructed as a URL; otherwise it throws 'Audio is not a URL'.","triggerScenarios":"Calling audio.asUrl() on an Audio instance created from base64 data (or vice versa) instead of a URL.","commonSituations":"Receiving media from an LLM response as base64 and assuming it's a URL, or mixing up which constructor (fromUrl vs fromBase64) produced the object.","solutions":["Check audio.isUrl() before calling asUrl().","Use asBase64() when the audio holds base64 data.","Construct the Audio with Audio.fromUrl if you need URL access later."],"exampleFix":"// before\nconst url = audio.asUrl(); // throws for base64 audio\n// after\nconst url = audio.isUrl() ? audio.asUrl() : null;","handlingStrategy":"type-guard","validationCode":"if (audio.isUrl()) { /* safe to call asUrl */ }","typeGuard":"function isUrlAudio(audio) { return typeof audio.isUrl === 'function' && audio.isUrl(); }","tryCatchPattern":"try {\n  const url = audio.asUrl();\n} catch (e) {\n  if (e.message === 'Audio is not a URL') { /* fall back to asBase64 */ }\n  else throw e;\n}","preventionTips":["Track how each media object was constructed (URL vs base64).","Call isUrl()/type checks before accessor use."],"tags":["typescript","audio","media","state-error"],"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-23T08:17:48.524Z"}