langchain-ai/deepagents · error · ValueError

project is only valid for the langsmith service, not {provid

Error message

project is only valid for the langsmith service, not {provider!r}

What it means

`set_stored_key` accepts an optional `project` field, but only for the LangSmith service. It lazily imports `is_langsmith` from model_config (avoiding a circular dependency) and raises `ValueError` if a `project` is supplied for any other provider, since non-LangSmith credentials have no project concept.

Source

Thrown at libs/code/deepagents_code/auth_store.py:499

        "type": "api_key",
        "key": cleaned,
        "added_at": datetime.now(tz=UTC).isoformat(timespec="seconds"),
    }
    cleaned_base_url = base_url.strip() if base_url else ""
    if cleaned_base_url:
        entry["base_url"] = cleaned_base_url
    cleaned_project = project.strip() if project else ""
    if cleaned_project:
        # A project name is meaningful only for the LangSmith tracing service;
        # enforce the invariant at the write boundary so a stray project can
        # never be persisted onto an unrelated provider, regardless of caller.
        # Lazy import avoids a circular dependency (model_config imports this
        # module), matching the pattern in `auth_path`.
        from deepagents_code.model_config import is_langsmith

        if not is_langsmith(provider):
            msg = f"project is only valid for the langsmith service, not {provider!r}"
            raise ValueError(msg)
        entry["project"] = cleaned_project
    creds[provider] = entry
    data["version"] = _STORAGE_VERSION
    data["credentials"] = creds
    warnings = _write_raw_or_raise(data)
    logger.debug("Stored credential for provider %s", provider)
    return WriteOutcome(warnings=warnings)


def delete_stored_key(provider: str) -> DeleteOutcome:
    """Remove a stored credential for `provider`.

    Args:
        provider: Provider identifier.

    Returns:
        A `DeleteOutcome` whose `removed` flag reports whether a credential was
        present, and whose `warnings` tuple lists chmod failures from the

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Omit the project argument for non-LangSmith providers: set_stored_key("anthropic", key).
  2. Use the exact provider identifier the library expects for LangSmith (verify what is_langsmith accepts) before passing project.
  3. If you need to record project info for other providers, store it in your own config rather than the credential store.

Example fix

// before
set_stored_key(provider, key, project=project)  # provider="anthropic" -> ValueError
// after
kwargs = {"project": project} if is_langsmith(provider) else {}
set_stored_key(provider, key, **kwargs)
Defensive patterns

Strategy: validation

Validate before calling

from deepagents_code.model_config import is_langsmith
def safe_set(provider: str, key: str, project: str | None = None) -> None:
    if project and not is_langsmith(provider):
        raise UsageError(f"project applies only to langsmith, got {provider!r}")
    set_stored_key(provider, key, project=project)

Type guard

def _accepts_project(provider: str) -> TypeGuard[str]:
    return is_langsmith(provider)

Try / catch

try:
    set_stored_key(provider, key, project=project)
except ValueError as exc:
    if "project is only valid for the langsmith service" in str(exc):
        set_stored_key(provider, key)  # retry without project
    else:
        raise

Prevention

When it happens

Trigger: Calling set_stored_key(provider, key, project="my-project") where provider is not recognized by is_langsmith() — e.g. set_stored_key("anthropic", key, project="x").

Common situations: A generic config loader that passes project for every provider; copy-pasting LangSmith setup code for another provider; case/alias mismatch such as "langsmith " vs "LangSmith" if is_langsmith is exact-match.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/a3ce31d1b53ee7ae. Report an issue: GitHub.