Skip to content

DurableAgent hardcodes supportedUrls: {} causing AI_DownloadError for image URLs #1376

@DannyAziz

Description

@DannyAziz

Bug Report

Description

DurableAgent hardcodes supportedUrls: {} when calling convertToLanguageModelPrompt, which tells the AI SDK that the model supports no image URLs. This forces the SDK to download every image URL via global fetch, which is unavailable in the Workflow runtime, causing an AI_DownloadError.

Steps to Reproduce

  1. Create a workflow using DurableAgent with an Anthropic or OpenAI model
  2. Pass messages containing image URL parts (e.g. { type: "image", image: new URL("https://example.com/image.png") })
  3. Call agent.stream({ messages, ... })

Expected Behavior

Image URLs should be passed through to the model provider (Anthropic/OpenAI), which natively supports fetching image URLs server-side. No client-side download should be attempted.

Actual Behavior

The AI SDK attempts to download the image using global fetch, which crashes with:

AI_DownloadError: Failed to download https://example.com/image.png:
Error: Global "fetch" is unavailable in workflow functions.
Use the "fetch" step function from "workflow" to make HTTP requests.

Root Cause

In packages/ai/dist/agent/durable-agent.js:

const modelPrompt = await convertToLanguageModelPrompt({
    prompt,
    supportedUrls: {},  // <-- hardcoded empty, ignores model's actual declaration
    download: options.experimental_download,
});

Meanwhile, the underlying @ai-sdk/anthropic provider correctly declares:

supportedUrls: () => ({
    "image/*": [/^https?:\/\/.*$/],
    "application/pdf": [/^https?:\/\/.*$/]
})

Because DurableAgent overrides this with {}, the SDK's createDefaultDownloadFunction attempts to download all image URLs instead of passing them through.

Suggested Fix

Forward the underlying model's supportedUrls instead of hardcoding an empty object:

const modelPrompt = await convertToLanguageModelPrompt({
    prompt,
    supportedUrls: await model.supportedUrls,  // forward model's declaration
    download: options.experimental_download,
});

Alternatively, if there are reasons to not forward supportedUrls, the default download function should use the workflow fetch step instead of global fetch.

Workaround

Pass a custom experimental_download that returns null for all URLs:

const result = await agent.stream({
    messages,
    experimental_download: async (urls) => urls.map(() => null),
    // ...
});

Environment

  • @workflow/ai: 4.0.1-beta.54
  • ai: 6.0.116
  • @ai-sdk/anthropic: 3.0.58
  • Deployed on Vercel with Workflow runtime

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions