fix(claude-code): keep the no-database hint on skill_hub and warn that the remove step uninstalls plugins

This commit is contained in:
mateo-berri 2026-10-29 02:45:08 -07:00
parent e30731c043
commit 8e989a0637
4 changed files with 10 additions and 5 deletions

View file

@ -371,9 +371,9 @@ async def public_skill_hub():
from litellm.proxy.anthropic_endpoints.claude_code_endpoints.claude_code_marketplace import (
MANIFEST_FIELDS,
get_installation_preference,
get_prisma_client,
)
from litellm.proxy.common_utils.claude_code_marketplace_auth import marketplace_auth_required
from litellm.proxy.proxy_server import prisma_client
from litellm.types.proxy.claude_code_endpoints import (
ListPluginsResponse,
PluginListItem,
@ -381,8 +381,9 @@ async def public_skill_hub():
if marketplace_auth_required():
return ListPluginsResponse(plugins=[], count=0)
if prisma_client is None:
raise HTTPException(status_code=500, detail=CommonProxyErrors.db_not_connected_error.value)
try:
prisma_client: Final = await get_prisma_client()
plugins: Final = await _plugin_table(prisma_client).find_many(where={"enabled": True})
items: Final = []
for plugin in plugins:

View file

@ -20,6 +20,7 @@ from litellm.proxy.auth.user_api_key_auth import user_api_key_auth
from litellm.proxy.db.health_check_latest import LatestHealthCheckRow
from litellm.proxy.public_endpoints import router
from litellm.router_strategy.complexity_router.fuse_presets import get_fuse_presets
from litellm.types.proxy.common_proxy_errors import CommonProxyErrors
from litellm.types.proxy.management_endpoints.model_management_endpoints import (
ModelGroupInfoProxy,
)
@ -1802,7 +1803,7 @@ def test_public_skill_hub_500_body_carries_no_exception_text() -> None:
assert "db.internal" not in response.text
def test_public_skill_hub_without_a_database_answers_a_fixed_string_detail() -> None:
def test_public_skill_hub_without_a_database_answers_db_not_connected() -> None:
app: Final = FastAPI()
app.include_router(router)
@ -1813,4 +1814,4 @@ def test_public_skill_hub_without_a_database_answers_a_fixed_string_detail() ->
response: Final = TestClient(app).get("/public/skill_hub")
assert response.status_code == 500
assert response.json() == {"detail": "Failed to list skills"}
assert response.json() == {"detail": CommonProxyErrors.db_not_connected_error.value}

View file

@ -86,5 +86,6 @@ describe("SkillDetail marketplace setup", () => {
expect(screen.queryByText(/\/plugin marketplace add/)).not.toBeInTheDocument();
expect(screen.getByText(/"Authorization": "Bearer <your-litellm-key>"/)).toBeInTheDocument();
expect(screen.getByText("/plugin marketplace remove litellm")).toBeInTheDocument();
expect(screen.getByText(/uninstalls the plugins you installed from it/)).toBeInTheDocument();
});
});

View file

@ -239,7 +239,9 @@ const SkillDetail: React.FC<SkillDetailProps> = ({ skill, onBack }) => {
<>
<div className="mb-4 rounded-lg border border-warning/30 bg-warning/10 px-4 py-3">
<p className="m-0 mb-2 text-[13px] leading-relaxed text-muted-foreground">
If you added this marketplace before without a key, remove it first in Claude Code:
If you added this marketplace before without a key, remove it first in Claude Code. Removing it also
uninstalls the plugins you installed from it, so install them again from /plugin after you add the
snippet:
</p>
<pre className="m-0 bg-transparent font-mono text-[13px] text-foreground">
/plugin marketplace remove litellm