litellm - ✅(Solved) Fix [Bug]: AnthropicException 400 - vector_store_ids: Extra inputs are not permitted [2 pull requests, 6 comments, 6 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#23741Fetched 2026-04-08 00:49:28
View on GitHub
Comments
6
Participants
6
Timeline
28
Reactions
2
Author
Timeline (top)
subscribed ×10commented ×6referenced ×6cross-referenced ×3

Error Message

litellm.BadRequestError: AnthropicException - b'{"type":"error","error":{"type":"invalid_request_error","message":"vector_store_ids: Extra inputs are not permitted"}}'

Root Cause

Root cause: LiteLLM proxy injects vector_store_ids into the request body for internal RBAC / vector-store pre-call hooks (see proxy/auth/auth_checks.py and proxy/common_utils/http_parsing_utils.py). This parameter is intentionally an OpenAI Assistants API concept that Anthropic does not recognise.

Fix Action

Fix

Strip vector_store_ids and vector_store_id from optional_params before building the payload, alongside the existing is_vertex_request cleanup:

# Remove internal LiteLLM parameters that should not be sent to Anthropic API
optional_params.pop("is_vertex_request", None)
optional_params.pop("vector_store_ids", None)
optional_params.pop("vector_store_id", None)

A PR with fix + tests is attached.

PR fix notes

PR #23742: fix(anthropic): strip vector_store_ids from request payload to prevent 400 error

Description (problem / solution / changelog)

Summary

  • Strip vector_store_ids and vector_store_id from optional_params in AnthropicConfig.transform_request() before building the final request payload
  • These are OpenAI Assistants API parameters injected by LiteLLM proxy for internal RBAC/vector-store hooks — Anthropic rejects them with 400: Extra inputs are not permitted
  • Adds 2 unit tests covering both the stripping behavior and the no-op case

Problem

AnthropicConfig.transform_request() builds the Anthropic payload via **optional_params. LiteLLM proxy injects vector_store_ids into the request body for internal pre-call hooks (proxy/auth/auth_checks.py, http_parsing_utils.py). This parameter leaks through to Anthropic, causing:

AnthropicException - {"type":"error","error":{"type":"invalid_request_error","message":"vector_store_ids: Extra inputs are not permitted"}}

is_vertex_request was already being stripped at this same location — this PR extends that pattern to cover vector_store_ids and vector_store_id.

Changes

  • litellm/llms/anthropic/chat/transformation.py: pop vector_store_ids and vector_store_id before data = {..., **optional_params}
  • tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py: 2 new mock-only tests

Related

Fixes #23741

Pre-Submission checklist

  • I have Added testing in the tests/litellm/ directory
  • My PR's scope is as isolated as possible, it only solves 1 specific problem

Changed files

  • litellm/llms/anthropic/chat/transformation.py (modified, +2/-0)
  • tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py (modified, +40/-0)

PR #23974: fix(ui): stop injecting empty vector_store_ids into model litellm_params on save

Description (problem / solution / changelog)

Summary

  • Admin UI model edit form unconditionally injects empty/zero values for vector_store_ids, guardrails, input_cost_per_token, and output_cost_per_token into the update payload, even when the user hasn't touched those fields
  • Fix: apply conditional guards — only include these fields when explicitly set, otherwise delete them from the payload

Problem

The handleSaveChanges function in model_info_view.tsx always includes these fields in the update payload:

// Before fix:
input_cost_per_token: values.input_cost / 1_000_000,   // 0/1M = 0.0 when empty
output_cost_per_token: values.output_cost / 1_000_000,  // 0/1M = 0.0 when empty

When a user edits a model to change only the credential (or any other field), the empty cost fields produce input_cost_per_token: 0.0 and output_cost_per_token: 0.0, which:

  1. Overrides the built-in pricing table with custom $0 pricing
  2. Silently disables spend tracking for the model
  3. Bypasses budget enforcement (spend never increments)
  4. Causes LiteLLM's reported spend to diverge from cloud provider billing

On one production deployment, this caused ~$6,500 of untracked Claude spend over 14 days before the root cause was identified.

The same pattern applies to vector_store_ids: [] (causes Anthropic 400 errors) and guardrails: [] (clears configured guardrails).

Fix

Apply the same guard pattern already used for litellm_credential_name:

// After fix:
if (values.input_cost != null && values.input_cost !== "") {
  updatedLitellmParams.input_cost_per_token = values.input_cost / 1_000_000;
} else {
  delete updatedLitellmParams.input_cost_per_token;
}

Test plan

  • should not inject empty vector_store_ids into litellm_params on save
  • should preserve non-empty vector_store_ids in litellm_params on save
  • should not inject empty vector_store_ids when model previously had empty array
  • should remove vector_store_ids when user clears all vector stores
  • should not inject empty guardrails into litellm_params on save
  • should preserve non-empty guardrails in litellm_params on save
  • should remove guardrails when user clears all guardrails
  • should not inject input_cost_per_token: 0 when cost fields are empty on save
  • should preserve explicitly set cost values on save

Generated with Claude Code

Changed files

  • ui/litellm-dashboard/src/components/model_info_view.test.tsx (modified, +423/-1)
  • ui/litellm-dashboard/src/components/model_info_view.tsx (modified, +21/-11)

Code Example

litellm.BadRequestError: AnthropicException - b'{"type":"error","error":{"type":"invalid_request_error","message":"vector_store_ids: Extra inputs are not permitted"}}'

---

data = {
    "model": model,
    "messages": anthropic_messages,
    **optional_params,     # ← vector_store_ids leaks through here
}

---

import litellm

response = litellm.completion(
    model="anthropic/claude-3-5-sonnet-20240620",
    messages=[{"role": "user", "content": "Hello"}],
    vector_store_ids=["vs_abc123"],  # passed as extra kwarg or injected by proxy
)
# → litellm.BadRequestError: AnthropicException 400 - vector_store_ids: Extra inputs are not permitted

---

litellm.BadRequestError: AnthropicException - b'{"type":"error","error":{"type":"invalid_request_error","message":"vector_store_ids: Extra inputs are not permitted"},"request_id":"req_011CZ6nPSDUqfyePACZeNUAE"}'
Received Model Group=anthropic/claude-sonnet-4-6
LiteLLM Retried: 3 times

---

# Remove internal LiteLLM parameters that should not be sent to Anthropic API
optional_params.pop("is_vertex_request", None)
optional_params.pop("vector_store_ids", None)
optional_params.pop("vector_store_id", None)
RAW_BUFFERClick to expand / collapse

Check for existing issues

  • I have searched the existing issues and checked that my issue is not a duplicate.

What happened?

When routing requests through LiteLLM to Anthropic models, the Anthropic API returns a 400 error if the request body contains vector_store_ids or vector_store_id:

litellm.BadRequestError: AnthropicException - b'{"type":"error","error":{"type":"invalid_request_error","message":"vector_store_ids: Extra inputs are not permitted"}}'

Root cause: LiteLLM proxy injects vector_store_ids into the request body for internal RBAC / vector-store pre-call hooks (see proxy/auth/auth_checks.py and proxy/common_utils/http_parsing_utils.py). This parameter is intentionally an OpenAI Assistants API concept that Anthropic does not recognise.

In AnthropicConfig.transform_request() the final payload is built with:

data = {
    "model": model,
    "messages": anthropic_messages,
    **optional_params,     # ← vector_store_ids leaks through here
}

is_vertex_request is already stripped before this point, but vector_store_ids / vector_store_id are not.

Steps to Reproduce

import litellm

response = litellm.completion(
    model="anthropic/claude-3-5-sonnet-20240620",
    messages=[{"role": "user", "content": "Hello"}],
    vector_store_ids=["vs_abc123"],  # passed as extra kwarg or injected by proxy
)
# → litellm.BadRequestError: AnthropicException 400 - vector_store_ids: Extra inputs are not permitted

Relevant log output

litellm.BadRequestError: AnthropicException - b'{"type":"error","error":{"type":"invalid_request_error","message":"vector_store_ids: Extra inputs are not permitted"},"request_id":"req_011CZ6nPSDUqfyePACZeNUAE"}'
Received Model Group=anthropic/claude-sonnet-4-6
LiteLLM Retried: 3 times

Fix

Strip vector_store_ids and vector_store_id from optional_params before building the payload, alongside the existing is_vertex_request cleanup:

# Remove internal LiteLLM parameters that should not be sent to Anthropic API
optional_params.pop("is_vertex_request", None)
optional_params.pop("vector_store_ids", None)
optional_params.pop("vector_store_id", None)

A PR with fix + tests is attached.

What part of LiteLLM is this about?

SDK (litellm Python package) + Proxy

What LiteLLM version are you on?

main (also reproducible on recent releases)

extent analysis

Fix Plan

To resolve the issue, we need to modify the AnthropicConfig.transform_request() method to remove the vector_store_ids and vector_store_id parameters from the optional_params dictionary before building the payload.

Here are the steps:

  • Open the AnthropicConfig.transform_request() method in your code editor.
  • Add the following lines to remove the unwanted parameters:
optional_params.pop("vector_store_ids", None)
optional_params.pop("vector_store_id", None)

The updated code should look like this:

# Remove internal LiteLLM parameters that should not be sent to Anthropic API
optional_params.pop("is_vertex_request", None)
optional_params.pop("vector_store_ids", None)
optional_params.pop("vector_store_id", None)

data = {
    "model": model,
    "messages": anthropic_messages,
    **optional_params,
}

Verification

To verify that the fix worked, you can run the following test:

import litellm

response = litellm.completion(
    model="anthropic/claude-3-5-sonnet-20240620",
    messages=[{"role": "user", "content": "Hello"}],
    vector_store_ids=["vs_abc123"],  # passed as extra kwarg or injected by proxy
)
print(response)  # Should not raise a BadRequestError

If the response is successful, it means the fix was applied correctly.

Extra Tips

Make sure to test the fix thoroughly to ensure it doesn't introduce any new issues. Additionally, consider adding tests to cover this specific scenario to prevent regressions in the future.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING