BerriAI/litellm · error · HTTPException
URL source must include 'url' field (e.g., 'https://github.c
Error message
URL source must include 'url' field (e.g., 'https://github.com/org/repo.git')
What it means
400 thrown by _validate_plugin_source() when the plugin source object declares "source": "url" but contains no "url" key. For the url source type LiteLLM needs the full clone URL (e.g. https://github.com/org/repo.git); the type tag alone carries no location information.
Source
Thrown at litellm/proxy/anthropic_endpoints/claude_code_endpoints/claude_code_marketplace.py:177
# Allowlist for git-subdir paths: one or more segments separated by '/'.
# Each segment must start with an alphanumeric character and contain only
# alphanumeric characters, dots, hyphens, and underscores.
# This implicitly blocks '..', leading '/', backslashes, and percent-encoded sequences.
_VALID_GIT_SUBDIR_PATH_RE: Final = re.compile(r"^[a-zA-Z0-9][a-zA-Z0-9._-]*(/[a-zA-Z0-9][a-zA-Z0-9._-]*)*$")
def _validate_plugin_source(source: Mapping[str, str]) -> None:
"""Validate plugin source format, raising HTTPException on invalid input."""
source_type: Final = source.get("source")
if source_type == "github":
if "repo" not in source:
raise HTTPException(
status_code=400,
detail={"error": "GitHub source must include 'repo' field (e.g., 'org/repo')"},
)
elif source_type == "url":
if "url" not in source:
raise HTTPException(
status_code=400,
detail={"error": "URL source must include 'url' field (e.g., 'https://github.com/org/repo.git')"},
)
elif source_type == "git-subdir":
if not source.get("url"):
raise HTTPException(
status_code=400,
detail={
"error": "git-subdir source must include 'url' field (e.g., 'https://github.com/org/repo.git')"
},
)
if not source.get("path"):
raise HTTPException(
status_code=400,
detail={"error": "git-subdir source must include 'path' field (e.g., 'plugins/plugin-name')"},
)
if not _VALID_GIT_SUBDIR_PATH_RE.match(source["path"]):
raise HTTPException(View on GitHub (pinned to 77b7c6c40c)
Solutions
- Add the url field with a full git URL: "source": {"source": "url", "url": "https://github.com/org/repo.git"}.
- Verify the key name is exactly 'url' and the value is a non-empty string (note: for url sources the key presence is checked, for git-subdir the value is truthiness-checked).
- If you only know the GitHub org/repo, use "source": "github" with a "repo" field instead.
Example fix
# before
{"name": "my-plugin", "source": {"source": "url"}}
# after
{"name": "my-plugin", "source": {"source": "url", "url": "https://github.com/org/repo.git"}} Defensive patterns
Strategy: validation
Validate before calling
source = payload["source"]
if source.get("source") == "url" and not source.get("url"):
raise ValueError("url source requires a non-empty 'url' field") Type guard
type UrlSource = { source: 'url'; url: string };
function isUrlSource(s: unknown): s is UrlSource {
return (
!!s && typeof s === 'object' &&
(s as any).source === 'url' &&
typeof (s as any).url === 'string' && (s as any).url.length > 0
);
} Prevention
- Validate that source.url is a non-empty absolute https URL before sending.
- Derive the payload from config that fails loudly when the URL variable is unset (no silent empty strings).
When it happens
Trigger: POST /claude-code/plugins or PUT /claude-code/plugins/{name} with {"source": {"source": "url"}} — the url key missing, empty, or misspelled (e.g. "uri", "git_url", "clone_url").
Common situations: Copy-pasting a registration payload and deleting the url line while keeping the type; renaming fields to match an internal convention; code that reads the URL from an env var that is unset, producing a dict without the key.
Related errors
- GitHub source must include 'repo' field (e.g., 'org/repo')
- git-subdir source must include 'url' field (e.g., 'https://g
- git-subdir source must include 'path' field (e.g., 'plugins/
- source.source must be 'github', 'url', or 'git-subdir'
- Plugin name must be kebab-case (lowercase letters, numbers,
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/170e98aa5e0c28c9.
Report an issue: GitHub.