{"record":{"id":"16712bdeb7184de2","repo":"langchain-ai/deepagents","slug":"api-key-cannot-be-empty","errorCode":null,"errorMessage":"API key cannot be empty","messagePattern":"API key cannot be empty","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/auth_store.py","lineNumber":475,"sourceCode":"    Returns:\n        A `WriteOutcome` whose `warnings` tuple lists chmod failures the\n        caller should surface to the user. Empty on a clean save.\n\n    Raises:\n        ValueError: If `provider` or the stripped `key` is empty, or a non-empty\n            `project` is paired with a provider other than the `langsmith`\n            service.\n        RuntimeError: If the credential file is corrupt and cannot be read, or\n            the new file cannot be written (e.g. no disk space or an\n            unwritable state directory).\n    \"\"\"  # noqa: DOC502 - `RuntimeError` re-raised from `_read_raw`/`_write_raw_or_raise`\n    if not provider:\n        msg = \"Provider name cannot be empty\"\n        raise ValueError(msg)\n    cleaned = key.strip()\n    if not cleaned:\n        msg = \"API key cannot be empty\"\n        raise ValueError(msg)\n    data = _read_raw() or {}\n    creds = data.get(\"credentials\")\n    if not isinstance(creds, dict):\n        creds = {}\n    entry: dict[str, str] = {\n        \"type\": \"api_key\",\n        \"key\": cleaned,\n        \"added_at\": datetime.now(tz=UTC).isoformat(timespec=\"seconds\"),\n    }\n    cleaned_base_url = base_url.strip() if base_url else \"\"\n    if cleaned_base_url:\n        entry[\"base_url\"] = cleaned_base_url\n    cleaned_project = project.strip() if project else \"\"\n    if cleaned_project:\n        # A project name is meaningful only for the LangSmith tracing service;\n        # enforce the invariant at the write boundary so a stray project can\n        # never be persisted onto an unrelated provider, regardless of caller.\n        # Lazy import avoids a circular dependency (model_config imports this","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/auth_store.py#L457-L493","documentation":"`set_stored_key` strips whitespace from the supplied API key and raises `ValueError` if the result is empty. This prevents storing a blank credential that would silently fail at request time, and catches the common whitespace-only paste mistake.","triggerScenarios":"Calling set_stored_key(provider, \"\") or set_stored_key(provider, \"   \"), or via `_run_set`/`on_input_submitted` when the user submits an empty or whitespace-only key.","commonSituations":"Environment variable holding the key is unset so the script passes an empty string; copy-paste missed the actual key and grabbed only whitespace; a config file line like `KEY=` resolved to empty.","solutions":["Supply the actual API key string, e.g. set_stored_key(\"anthropic\", \"sk-...\").","Check the source env var / config value is populated before calling (fail fast with a clear message).","Re-run /auth and paste the full key, including any prefixes like `sk-` or `lsv2_`."],"exampleFix":"// before\nkey = os.environ.get(\"ANTHROPIC_API_KEY\", \"\")\nset_stored_key(\"anthropic\", key)  # ValueError if unset\n// after\nkey = os.environ.get(\"ANTHROPIC_API_KEY\")\nif not key or not key.strip():\n    raise SystemExit(\"ANTHROPIC_API_KEY is not set\")\nset_stored_key(\"anthropic\", key)","handlingStrategy":"validation","validationCode":"def require_key(provider: str, key: str | None) -> str:\n    cleaned = (key or \"\").strip()\n    if not cleaned:\n        raise UsageError(f\"API key for {provider} is required\")\n    return cleaned\n# call site\nset_stored_key(provider, require_key(provider, os.environ.get(\"ANTHROPIC_API_KEY\")))","typeGuard":"def _is_nonempty_str(value: object) -> TypeGuard[str]:\n    return isinstance(value, str) and bool(value.strip())","tryCatchPattern":"try:\n    set_stored_key(provider, key)\nexcept ValueError as exc:\n    if \"API key cannot be empty\" in str(exc):\n        print(f\"no API key supplied for {provider}; set the env var or re-run /auth\")\n    else:\n        raise","preventionTips":["Verify the source env var is set and non-blank before reading it.","Validate pasted input (strip whitespace, check a plausible prefix like sk-/lsv2_) in your own UI.","Fail fast with a clear message instead of passing empty defaults like `os.getenv(..., \"\")`.","Re-run /auth interactively when scripting pipelines report an empty key."],"tags":["auth","validation","input-error"],"backgroundTag":"empty-required-argument","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}