{"record":{"id":"dd09f26da9854979","repo":"BerriAI/litellm","slug":"set-store-model-in-db-true-in-your-env-to-ena","errorCode":null,"errorMessage":"Set `'STORE_MODEL_IN_DB='True'` in your env to enable this feature.","messagePattern":"Set `'STORE_MODEL_IN_DB='True'` in your env to enable this feature\\.","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"litellm/proxy/management_endpoints/cache_settings_endpoints.py","lineNumber":601,"sourceCode":"    This endpoint:\n    1. Encrypts sensitive fields (passwords, etc.)\n    2. Saves to LiteLLM_CacheConfig table\n    3. Reinitializes cache with new settings\n    \"\"\"\n    from litellm.proxy.proxy_server import (\n        prisma_client,\n        proxy_config,\n        store_model_in_db,\n    )\n\n    if prisma_client is None:\n        raise HTTPException(\n            status_code=500,\n            detail={\"error\": \"Database not connected. Please connect a database.\"},\n        )\n\n    if store_model_in_db is not True:\n        raise HTTPException(\n            status_code=500,\n            detail={\"error\": \"Set `'STORE_MODEL_IN_DB='True'` in your env to enable this feature.\"},\n        )\n\n    try:\n        # Read the stored row first: its decrypted values back any credential the\n        # caller echoed back redacted, and its key set drives the audit diff.\n        existing_row: Final = await _cache_config_table(prisma_client).find_unique(where={\"id\": \"cache_config\"})\n        before_settings: dict[str, object] | None = None\n        saved_settings: dict[str, object] = {}\n        if existing_row is not None and existing_row.cache_settings:\n            before_settings = _parse_stored_settings(existing_row.cache_settings)\n            saved_settings = proxy_config._decrypt_db_variables(variables_dict=before_settings)\n        action: Final[AUDIT_ACTIONS] = \"updated\" if existing_row is not None else \"created\"\n\n        # Preserve stored secrets behind any redacted or omitted credential, then\n        # resolve the url-vs-discrete-fields precedence.\n        cache_settings: Final = _resolve_cache_url_precedence(_merge_over_saved(request.cache_settings, saved_settings))","sourceCodeStart":583,"sourceCodeEnd":619,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/cache_settings_endpoints.py#L583-L619","documentation":"Saving cache settings via POST /cache/settings additionally requires the STORE_MODEL_IN_DB feature flag: proxy_server reads it with get_secret_bool(\"STORE_MODEL_IN_DB\", ...) and this endpoint refuses with HTTP 500 when it is not exactly True. The gate exists because settings must round-trip through the database, which is only enabled when the deployment opts into DB-stored config. The odd quoting in the message ('STORE_MODEL_IN_DB='True'') is cosmetic in the source string.","triggerScenarios":"POST /cache/settings on a proxy where DATABASE_URL is set but STORE_MODEL_IN_DB is unset/false; enabling the flag only in config but not env (or vice versa depending on how the deployment reads secrets); forgetting the flag after a redeploy.","commonSituations":"Standing up the Admin UI cache editor for the first time; migrations of docker-compose files that drop env entries; flag set as string \"True\" vs boolean in YAML causing get_secret_bool to parse false.","solutions":["Set the env var: export STORE_MODEL_IN_DB=\"True\" (or add it to the container/deployment env)","Equivalently enable it in the config under general_settings: store_model_in_db: true, then restart the proxy","Confirm both requirements hold: DATABASE_URL set AND STORE_MODEL_IN_DB=True, then retry POST /cache/settings"],"exampleFix":"# before\nexport DATABASE_URL=\"postgresql://...\"\nlitellm  # POST /cache/settings -> 500 Set 'STORE_MODEL_IN_DB=True'\n\n# after\nexport DATABASE_URL=\"postgresql://...\"\nexport STORE_MODEL_IN_DB=\"True\"\nlitellm  # POST /cache/settings -> 200","handlingStrategy":"validation","validationCode":"import os\n\n# The flag must be exactly True (string 'True' from env) on the proxy side\nflag = os.getenv(\"STORE_MODEL_IN_DB\", \"False\")\nassert flag.lower() == \"true\", f\"STORE_MODEL_IN_DB={flag!r}; set it to True to save cache settings\"","typeGuard":"def store_model_in_db_enabled(value: object) -> bool:\n    return isinstance(value, str) and value.strip().lower() == \"true\"","tryCatchPattern":"import httpx\n\ntry:\n    httpx.post(f\"{PROXY_URL}/cache/settings\", json=settings, headers=hdrs).raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 500 and \"STORE_MODEL_IN_DB\" in e.response.text:\n        raise RuntimeError(\"enable STORE_MODEL_IN_DB=True on the proxy, then retry\") from e\n    raise","preventionTips":["Set STORE_MODEL_IN_DB=True whenever DB-backed settings management is planned","Beware YAML boolean vs string ('True' vs true) inconsistencies when the flag is read from secrets"],"tags":["litellm-proxy","feature-flag","env-var","cache","configuration"],"backgroundTag":"missing-env-var","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T08:17:14.275Z"}