Skip to content

@ai-sdk/anthropic: ANTHROPIC_BASE_URL not normalized — bare-host form silently produces 404 in Claude Code / Cursor environments #15580

@AkshatRaj00

Description

@AkshatRaj00

Description

Summary

@ai-sdk/anthropic reads ANTHROPIC_BASE_URL from the environment but does not normalize it — so the bare-host form (https://api.anthropic.com, which is what Claude Code and Cursor inject) silently produces 404 Not Found on every Anthropic call.

This is a silent, environment-specific breakage: the error message (AI_APICallError: Not Found) gives no hint that the issue is a missing /v1 in the base URL, so developers spend hours debugging.


Root Cause

In packages/anthropic/src/anthropic-provider.ts:

// Default baseURL includes /v1
baseURL: options.baseURL ?? process.env.ANTHROPIC_BASE_URL ?? 'https://api.anthropic.com/v1'

And in the request builder:

url: `${this.config.baseURL}/messages`

So the final URL is constructed by simple string concatenation. When ANTHROPIC_BASE_URL=https://api.anthropic.com (no /v1), the result is:

https://api.anthropic.com/messages   ← 404

instead of the correct:

https://api.anthropic.com/v1/messages   ← 200

Why This Matters — Claude Code / Cursor

Claude Code injects ANTHROPIC_BASE_URL=https://api.anthropic.com (bare host) into all child processes. This follows the official @anthropic-ai/sdk convention, which appends /v1 internally. Any app using @ai-sdk/anthropic inside Claude Code silently breaks the moment the env var is present.

Same behavior exists in:

  • Cursor agent mode
  • LiteLLM proxy setups that document the bare-host form
  • Developers who configured their shell/CI following the official Anthropic SDK docs

Minimal Reproduction

ANTHROPIC_BASE_URL=https://api.anthropic.com \
  ANTHROPIC_API_KEY=sk-ant-... \
  node -e "
    import('@ai-sdk/anthropic').then(async ({ anthropic }) => {
      const { generateText } = await import('ai');
      const result = await generateText({
        model: anthropic('claude-opus-4-5-20250929'),
        prompt: 'Say hello'
      });
      console.log(result.text);
    })
  "

Result: AI_APICallError: Not Found from https://api.anthropic.com/messages

Drop the env var → works fine.


Proposed Fix

Normalize baseURL at construction time in anthropic-provider.ts:

function normalizeAnthropicBaseURL(url: string): string {
  // Accept both bare-host and /v1 forms; always return the /v1 form
  const cleaned = url.replace(/\/+$/, '').replace(/\/v1$/, '');
  return `${cleaned}/v1`;
}

const resolvedBaseURL = normalizeAnthropicBaseURL(
  options.baseURL ?? process.env.ANTHROPIC_BASE_URL ?? 'https://api.anthropic.com'
);

This normalizes all variants correctly:

Input Output Status
https://api.anthropic.com https://api.anthropic.com/v1
https://api.anthropic.com/v1 https://api.anthropic.com/v1
https://api.anthropic.com/v1/ https://api.anthropic.com/v1
https://my.proxy.com https://my.proxy.com/v1
https://my.proxy.com/v1 https://my.proxy.com/v1

Related


AI SDK Version

Reproduced on latest stable @ai-sdk/anthropic

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions