AI SDK ai@7.0.172: extract and decide need experimental_download for remote file URLs (November 13, 2026)
ai@7.0.172: experimental_extract and experimental_decide throw DownloadError on remote file URLs unless you pass experimental_download.
What changed
ai@7.0.172 was published on GitHub on November 13, 2026 at 05:57 UTC. It changes how experimental_extract and experimental_decide handle remote file URLs in state.
Before, the SDK downloaded those files through the global fetch. Now you must pass an explicit experimental_download hook. Without it, a remote file URL is rejected with DownloadError.
Inline file data still works without the hook: bytes, base64 content and data URLs.
experimental_extract itself is new. It was added one release earlier, in ai@7.0.171 (November 12, 2026).
The release also updates @ai-sdk/provider-utils to 5.0.81 and @ai-sdk/gateway to 4.0.145.
What to do
- If you call
experimental_extractorexperimental_decidewith file URLs, addexperimental_downloadbefore you upgrade, or the calls will fail. - The hook takes the function returned by
createDownload({ fetch }). - For URLs you do not control (user input, links picked by a model), give
createDownloada transport that checks DNS, such ascreateGuardedFetch()on Node.js. Install it withnpm install guarded-fetch@^0.3.0. It needs Node.js 20.19 or later. createDownload()with no customfetchuses the global fetch and gives no DNS protection.- The model's own
fetchoption does not cover these downloads, so a guarded fetch on the provider is not enough. - Do not replace
globalThis.fetchwith the guarded transport. Close the guarded fetch withclose()at shutdown. - If you only send inline files, nothing changes.
The docs show the hook with generateText. The same experimental_download option is passed to experimental_extract and experimental_decide:
import { createOpenAI } from '@ai-sdk/openai';
import { createGuardedFetch } from 'guarded-fetch';
import { createDownload, generateText } from 'ai';
const fetch = createGuardedFetch();
const openai = createOpenAI({ fetch });
const download = createDownload({ fetch, maxBytes: 20 * 1024 * 1024 });
try {
const result = await generateText({
model: openai('gpt-4.1'),
messages: [
{
role: 'user',
content: [
{
type: 'file',
data: new URL('https://example.com/report.pdf'),
mediaType: 'application/pdf',
},
],
},
],
experimental_download: download,
});
console.log(result.text);
} finally {
await fetch.close();
}