BerriAI/litellm · error · NotImplementedError

Write operations are not implemented for {self.secret_manage

Error message

Write operations are not implemented for {self.secret_manager_name}. Override async_write_secret() to add write support.

What it means

CustomSecretManager guarantees read-path semantics only; async_write_secret is an optional-capability stub that raises NotImplementedError naming the manager and the method to override. Subclasses that only resolve reads (env vars, KV lookups) hit this the moment anything tries to persist a secret through them.

Source

Thrown at litellm/integrations/custom_secret_manager.py:178

        This is optional to implement. If your secret manager supports writing secrets,
        you can override this method.

        Args:
            secret_name: Name/path of the secret to write
            secret_value: Value to store
            description: Description of the secret
            optional_params: Additional parameters specific to your secret manager
            timeout: Request timeout
            tags: Optional tags to apply to the secret

        Returns:
            Response from the secret manager containing write operation details

        Raises:
            NotImplementedError: If write operations are not supported
        """
        raise NotImplementedError(
            f"Write operations are not implemented for {self.secret_manager_name}. "
            "Override async_write_secret() to add write support."
        )

    async def async_delete_secret(
        self,
        secret_name: str,
        recovery_window_in_days: int | None = 7,
        optional_params: dict | None = None,
        timeout: float | httpx.Timeout | None = None,
    ) -> dict:
        """
        Asynchronously delete a secret from your custom secret manager.

        This is optional to implement. If your secret manager supports deleting secrets,
        you can override this method.

        Args:

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Override async_write_secret in your subclass to call your backend's write API and return its response dict
  2. Skip/branch write flows for read-only managers using a capability check before calling
  3. Use a litellm built-in manager with write support (e.g. cloud/Kubernetes backends) where writes are required

Example fix

# before
class EnvSecrets(CustomSecretManager):
    async def async_read_secret(self, name, optional_params=None, timeout=None): ...
await mgr.async_write_secret('k', 'v')  # NotImplementedError

# after
class EnvSecrets(CustomSecretManager):
    async def async_write_secret(self, secret_name, secret_value, description=None, optional_params=None, timeout=None, tags=None):
        os.environ[secret_name] = secret_value
        return {'name': secret_name, 'written': True}
Defensive patterns

Strategy: type-guard

Validate before calling

from litellm.integrations.custom_secret_manager import CustomSecretManager

if type(manager).async_write_secret is CustomSecretManager.async_write_secret:
    raise PermissionError(f'{manager.secret_manager_name} is read-only; skipping write')

Type guard

from litellm.integrations.custom_secret_manager import CustomSecretManager

def can_write_secrets(manager) -> bool:
    return type(manager).async_write_secret is not CustomSecretManager.async_write_secret

Try / catch

except NotImplementedError as e:
    if 'async_write_secret' in str(e):
        route the write to a manager that supports it; never swallow and pretend the secret was stored
    raise

Prevention

When it happens

Trigger: await manager.async_write_secret(secret_name, secret_value) on a read-only CustomSecretManager subclass; generic secret-lifecycle automation that writes-then-reads against whatever manager is configured.

Common situations: Wrapping a read-only secret source (SSM parameter reads, env fallbacks) as a CustomSecretManager and pointing write flows at it; testing a manager with a full CRUD harness.

Understand the failure class

Background: "NotImplementedError: Subclasses should override this method" / "must be implemented" — abstract method errors explained — this error's family across 40 libraries.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/f76ab807f02a951d. Report an issue: GitHub.