{"record":{"id":"f76ab807f02a951d","repo":"BerriAI/litellm","slug":"write-operations-are-not-implemented-for-self-sec","errorCode":null,"errorMessage":"Write operations are not implemented for {self.secret_manager_name}. Override async_write_secret() to add write support.","messagePattern":"Write operations are not implemented for (.+?)\\. Override async_write_secret\\(\\) to add write support\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/custom_secret_manager.py","lineNumber":178,"sourceCode":"\n        This is optional to implement. If your secret manager supports writing secrets,\n        you can override this method.\n\n        Args:\n            secret_name: Name/path of the secret to write\n            secret_value: Value to store\n            description: Description of the secret\n            optional_params: Additional parameters specific to your secret manager\n            timeout: Request timeout\n            tags: Optional tags to apply to the secret\n\n        Returns:\n            Response from the secret manager containing write operation details\n\n        Raises:\n            NotImplementedError: If write operations are not supported\n        \"\"\"\n        raise NotImplementedError(\n            f\"Write operations are not implemented for {self.secret_manager_name}. \"\n            \"Override async_write_secret() to add write support.\"\n        )\n\n    async def async_delete_secret(\n        self,\n        secret_name: str,\n        recovery_window_in_days: int | None = 7,\n        optional_params: dict | None = None,\n        timeout: float | httpx.Timeout | None = None,\n    ) -> dict:\n        \"\"\"\n        Asynchronously delete a secret from your custom secret manager.\n\n        This is optional to implement. If your secret manager supports deleting secrets,\n        you can override this method.\n\n        Args:","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/custom_secret_manager.py#L160-L196","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Override async_write_secret in your subclass to call your backend's write API and return its response dict","Skip/branch write flows for read-only managers using a capability check before calling","Use a litellm built-in manager with write support (e.g. cloud/Kubernetes backends) where writes are required"],"exampleFix":"# before\nclass EnvSecrets(CustomSecretManager):\n    async def async_read_secret(self, name, optional_params=None, timeout=None): ...\nawait mgr.async_write_secret('k', 'v')  # NotImplementedError\n\n# after\nclass EnvSecrets(CustomSecretManager):\n    async def async_write_secret(self, secret_name, secret_value, description=None, optional_params=None, timeout=None, tags=None):\n        os.environ[secret_name] = secret_value\n        return {'name': secret_name, 'written': True}","handlingStrategy":"type-guard","validationCode":"from litellm.integrations.custom_secret_manager import CustomSecretManager\n\nif type(manager).async_write_secret is CustomSecretManager.async_write_secret:\n    raise PermissionError(f'{manager.secret_manager_name} is read-only; skipping write')","typeGuard":"from litellm.integrations.custom_secret_manager import CustomSecretManager\n\ndef can_write_secrets(manager) -> bool:\n    return type(manager).async_write_secret is not CustomSecretManager.async_write_secret","tryCatchPattern":"except NotImplementedError as e:\n    if 'async_write_secret' in str(e):\n        route the write to a manager that supports it; never swallow and pretend the secret was stored\n    raise","preventionTips":["Advertise write capability on secret-manager subclasses and check it before lifecycle flows","Never point generic write/rotate automation at read-only managers","Assert required capabilities in deployment smoke tests"],"tags":["notimplementederror","secret-manager","subclass-contract","litellm"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}