crewAIInc/crewAI · error · ValueError
provider is required
Error message
provider is required
What it means
Thrown by normalize_provider() in crewai_files.formatting.api when the provider argument is None or an empty string. The library needs a provider name to select the correct formatter (gemini, google, anthropic, claude, bedrock, etc.), so it refuses to guess and raises ValueError('provider is required'). It is a caller-side programming error, not an environment issue.
Source
Thrown at lib/crewai-files/src/crewai_files/formatting/api.py:36
from crewai_files.processing.processor import FileProcessor
from crewai_files.resolution.resolver import FileResolver, FileResolverConfig
from crewai_files.uploaders.factory import ProviderType
def _normalize_provider(provider: str | None) -> ProviderType:
"""Normalize provider string to ProviderType.
Args:
provider: Raw provider string.
Returns:
Normalized provider type.
Raises:
ValueError: If provider is None or empty.
"""
if not provider:
raise ValueError("provider is required")
provider_lower = provider.lower()
if "gemini" in provider_lower:
return "gemini"
if "google" in provider_lower:
return "google"
if "anthropic" in provider_lower:
return "anthropic"
if "claude" in provider_lower:
return "claude"
if "bedrock" in provider_lower:
return "bedrock"
if "aws" in provider_lower:
return "aws"
if "azure" in provider_lower:
return "azure"
if "gpt" in provider_lower:View on GitHub (pinned to 754d7323be)
Solutions
- Pass a non-empty provider string such as "anthropic", "openai", "google", "gemini", "bedrock" or "vertex_ai" (matching is case-insensitive substring based).
- If the provider comes from config, give it a default: provider = config.get("provider") or "openai".
- Validate at the boundary of your app (fail fast on startup) rather than deep in the formatting call.
- Add a unit test asserting ValueError is raised for None/empty so the contract stays locked.
Example fix
// before
provider = config.get("provider") # None when key missing
formatter = get_formatter(provider, ...)
# after
provider = config.get("provider")
if not provider:
raise ValueError("config must define 'provider'")
formatter = get_formatter(provider, ...) Defensive patterns
Strategy: validation
Validate before calling
provider = config.get("provider")
if not provider or not provider.strip():
raise ValueError("config must define a non-empty 'provider'") Type guard
def is_valid_provider(provider: object) -> TypeGuard[str]:
return isinstance(provider, str) and bool(provider.strip()) Try / catch
try:
formatter_api = build(provider)
except ValueError as e:
if "provider is required" in str(e):
raise ConfigError("LLM provider not configured") from e
raise Prevention
- Fail fast on startup: assert required config keys like provider before any agent runs.
- Give config reads explicit defaults (config.get('provider') or 'openai').
- Never forward Optional[str] fields unchecked into the formatting API.
When it happens
Trigger: Calling the formatting API entry point with provider=None, provider="", or provider=" " (any falsy value; note whitespace-only strings pass this check but then fall through the substring matching). Typically happens when the provider is read from an optional config field or dict that was never populated.
Common situations: Optional provider key missing from a config dict (config.get("provider") returns None); env var like os.environ.get("LLM_PROVIDER") unset; a default parameter left as None and forwarded unchecked; refactoring that dropped the provider argument.
Related errors
- Project name cannot be empty
- Project name '{name}' produces invalid folder name '{folder_
- No deployable project files were found.
- Missing required fields in OAuth2 configuration: [{', '.join
- Missing authentication provider required fields in OAuth2 co
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/f11d0ca2fd2b86eb.
Report an issue: GitHub.