BerriAI/litellm · error · HTTPException
str(e)
Error message
str(e)
What it means
Catch-all 500 from list_plugins (GET /claude-code/plugins). Any non-HTTPException during the Prisma find_many over the plugin table, manifest parsing, or the sort by created_at is logged as 'Error listing plugins' and surfaced as a bare str(e) 500 — the least informative of the module's error messages, so the log line is essential.
Source
Thrown at litellm/proxy/anthropic_endpoints/claude_code_endpoints/claude_code_marketplace.py:397
enabled=p.enabled,
created_at=p.created_at.isoformat() if p.created_at else None,
updated_at=p.updated_at.isoformat() if p.updated_at else None,
)
)
# Sort by created_at descending (newest first)
plugin_list.sort(key=lambda x: x.created_at or "", reverse=True)
return ListPluginsResponse(
plugins=plugin_list,
count=len(plugin_list),
)
except HTTPException:
raise
except Exception as e:
verbose_proxy_logger.exception("Error listing plugins: %s", e)
raise HTTPException(
status_code=500,
detail={"error": str(e)},
)
@router.get(
"/claude-code/plugins/{plugin_name}",
tags=["Claude Code Marketplace"],
dependencies=[Depends(user_api_key_auth)],
)
async def get_plugin(
plugin_name: str,
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
):
"""
Get details of a specific plugin.
Parameters:View on GitHub (pinned to 77b7c6c40c)
Solutions
- Check the proxy logs for 'Error listing plugins' to get the actual traceback.
- For a missing-table/relation error, restart the proxy with DATABASE_URL configured so Prisma migrations run and create the plugin table.
- For a JSONDecodeError, inspect manifest_json values in the plugin table and fix or delete the offending rows, then re-register those plugins.
- For connection errors, restore DB connectivity and retry — this GET is read-only and safe to retry.
Defensive patterns
Strategy: retry
Try / catch
for attempt in range(3):
resp = client.get(f"{base}/claude-code/plugins", headers=hdr)
if resp.status_code == 200:
return resp.json()["plugins"]
if resp.status_code == 500 and attempt < 2:
time.sleep(2 ** attempt) # transient DB issue; read-only so retry is safe
continue
resp.raise_for_status() Prevention
- Run migrations after every LiteLLM upgrade before serving traffic.
- Treat a 500 on this read-only list endpoint as transient first (retry), then investigate logs.
- Alert on 'Error listing plugins' log lines to catch corrupted rows early.
When it happens
Trigger: GET /claude-code/plugins when litellm_claudecodeplugintable is missing (un-migrated schema), when the DB connection has died, or when a row's manifest_json is invalid JSON that json.loads chokes on while building PluginListItem.
Common situations: Immediately after a LiteLLM version upgrade that added the marketplace feature, hitting the admin list endpoint before migrations ran; polling scripts that discover the DB was restarted; a plugin row inserted by hand or by a broken earlier registration.
Related errors
- Failed to generate marketplace: {e}
- Registration failed: {e}
- DB not connected. This endpoint needs a database; set DATABA
- urn:litellm:error:internal-server-error
- DB not connected. This endpoint needs a database; set DATABA
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/941ccf7e190a06b9.
Report an issue: GitHub.