{"record":{"id":"4f911ab131487ed8","repo":"BerriAI/litellm","slug":"missing-keys-missing-keys-in-environment-4f911a","errorCode":null,"errorMessage":"Missing keys={missing_keys} in environment.","messagePattern":"Missing keys=(.+?) in environment\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/integrations/openmeter.py","lineNumber":49,"sourceCode":"        super().__init__()\n        self.validate_environment()\n        self.async_http_handler = get_async_httpx_client(llm_provider=httpxSpecialProvider.LoggingCallback)\n        self.sync_http_handler = HTTPHandler()\n\n    def validate_environment(self):\n        \"\"\"\n        Expects\n        OPENMETER_API_ENDPOINT,\n        OPENMETER_API_KEY,\n\n        in the environment\n        \"\"\"\n        missing_keys: Final = []\n        if os.getenv(\"OPENMETER_API_KEY\", None) is None:\n            missing_keys.append(\"OPENMETER_API_KEY\")\n\n        if len(missing_keys) > 0:\n            raise Exception(f\"Missing keys={missing_keys} in environment.\")\n\n    def _common_logic(self, kwargs: dict, response_obj):\n        call_id: Final = response_obj.get(\"id\", kwargs.get(\"litellm_call_id\"))\n        dt: Final = get_utc_datetime().isoformat()\n        cost: Final = kwargs.get(\"response_cost\", None)\n        model: Final = kwargs.get(\"model\")\n        usage = {}\n        if (\n            isinstance(response_obj, litellm.ModelResponse) or isinstance(response_obj, litellm.EmbeddingResponse)\n        ) and hasattr(response_obj, \"usage\"):\n            usage = {\n                \"prompt_tokens\": response_obj[\"usage\"].get(\"prompt_tokens\", 0),\n                \"completion_tokens\": response_obj[\"usage\"].get(\"completion_tokens\", 0),\n                \"total_tokens\": response_obj[\"usage\"].get(\"total_tokens\"),\n            }\n\n        # OPENMETER_TRUST_REQUEST_USER (default \"true\"): when set to \"false\",\n        # the request-supplied `user` field is ignored and the subject is","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/openmeter.py#L31-L67","documentation":"OpenMeterLogger.validate_environment() runs in the callback's __init__ and raises a generic Exception when OPENMETER_API_KEY is absent from the environment. Despite the docstring mentioning OPENMETER_API_ENDPOINT too, only the API key is actually enforced — the endpoint falls back to https://openmeter.cloud. Because this fires at logger construction, adding 'openmeter' to your callbacks list without the env var crashes callback initialization (startup or first import of the callback).","triggerScenarios":"Adding openmeter to litellm_callbacks / litellm_settings.callbacks in config.yaml (or litellm.callbacks = ['openmeter'] in SDK usage) in a process where OPENMETER_API_KEY is unset. The error message formats the missing key(s) as a Python list, e.g. Missing keys=['OPENMETER_API_KEY'] in environment.","commonSituations":"Enabling OpenMeter cost logging after reading the docs but only setting the endpoint var; env var set in a local .env that the deployed container never loads; OPENMETER_API_KEY defined in a CI secrets mask but not exported; rotating keys and accidentally deleting the variable; expecting the endpoint to be required too and misreading which var failed.","solutions":["Set the API key: export OPENMETER_API_KEY=<your OpenMeter API key>","Optionally set the endpoint if not using OpenMeter Cloud: export OPENMETER_API_ENDPOINT=https://<your-endpoint> (the code appends /api/v1/events, so provide the base URL only)","Confirm the variable is visible to the process that constructs the callback (printenv OPENMETER_API_KEY inside the container/runtime)","Restart/redeploy the proxy or re-import the SDK so the callback reconstructs and validation passes"],"exampleFix":"# before\nlitellm_settings:\n  callbacks: [\"openmeter\"]\n# env: nothing set -> Exception at startup\n\n# after\nlitellm_settings:\n  callbacks: [\"openmeter\"]\n# env:\n# OPENMETER_API_KEY=<key>\n# OPENMETER_API_ENDPOINT=https://openmeter.cloud  # optional","handlingStrategy":"validation","validationCode":"import os\n\nif not os.getenv('OPENMETER_API_KEY'):\n    raise SystemExit('OPENMETER_API_KEY is required when the openmeter callback is enabled')\n# optional: sanity-check a custom endpoint base URL\nendpoint = os.getenv('OPENMETER_API_ENDPOINT', 'https://openmeter.cloud')\nassert endpoint.startswith('http'), 'OPENMETER_API_ENDPOINT must be a base http(s) URL'","typeGuard":null,"tryCatchPattern":"try:\n    from litellm.integrations.openmeter import OpenMeterLogger\n    cb = OpenMeterLogger()  # validate_environment runs here\nexcept Exception as e:\n    raise RuntimeError(f'OpenMeter callback misconfigured: {e}') from e","preventionTips":["Gate callback registration on presence of OPENMETER_API_KEY in your bootstrap code","Remember only the API key is validated — the endpoint silently defaults to openmeter.cloud, so set it explicitly for self-hosted","Store OpenMeter credentials in the same secret backend the deployment mounts","Smoke-test one metered call after enabling the callback and confirm events arrive in OpenMeter"],"tags":["openmeter","environment-variables","configuration","callback-init","startup"],"backgroundTag":"missing-env-var","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}