{"record":{"id":"bc7267837acaec6f","repo":"BerriAI/litellm","slug":"generated-czrn-is-invalid-czrn","errorCode":null,"errorMessage":"Generated CZRN is invalid: {czrn}","messagePattern":"Generated CZRN is invalid: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/cloudzero/cz_resource_names.py","lineNumber":96,"sourceCode":"        provider: str,\n        region: str,\n        owner_account_id: str,\n        resource_type: str,\n        cloud_local_id: str,\n    ) -> str:\n        \"\"\"Create a CZRN from individual components.\"\"\"\n        # Normalize components to ensure they meet CZRN requirements\n        service_type = self._normalize_component(service_type, allow_uppercase=True)\n        provider = self._normalize_component(provider)\n        region = self._normalize_component(region)\n        owner_account_id = self._normalize_component(owner_account_id)\n        resource_type = self._normalize_component(resource_type)\n        # cloud_local_id can contain pipes and other characters, so don't normalize it\n\n        czrn: Final = f\"czrn:{service_type}:{provider}:{region}:{owner_account_id}:{resource_type}:{cloud_local_id}\"\n\n        if not self.is_valid(czrn):\n            raise ValueError(f\"Generated CZRN is invalid: {czrn}\")\n\n        return czrn\n\n    def is_valid(self, czrn: str) -> bool:\n        \"\"\"Validate a CZRN string against the standard format.\"\"\"\n        return bool(self.CZRN_REGEX.match(czrn))\n\n    def extract_components(self, czrn: str) -> tuple[str, str, str, str, str, str]:\n        \"\"\"Extract all components from a CZRN.\n\n        Returns: (service_type, provider, region, owner_account_id, resource_type, cloud_local_id)\n        \"\"\"\n        match: Final = self.CZRN_REGEX.match(czrn)\n        if not match:\n            raise ValueError(f\"Invalid CZRN format: {czrn}\")\n\n        return cast(tuple[str, str, str, str, str, str], match.groups())\n","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/cloudzero/cz_resource_names.py#L78-L114","documentation":"ValueError raised by CZRNGenerator.create_from_components when the assembled string czrn:{service_type}:{provider}:{region}:{owner_account_id}:{resource_type}:{cloud_local_id} fails the format regex ^czrn:([a-z0-9-]+):([a-zA-Z0-9-]+):([a-z0-9-]+):([a-z0-9-]+):([a-z0-9-]+):(.+)$. All components except cloud_local_id are normalized, so the realistic failures are an EMPTY cloud_local_id (the czrn then ends with ':' and (.+) cannot match), a cloud_local_id containing a newline, or an UPPERCASE service_type — normalization allows uppercase there (allow_uppercase=True) but the regex's first group only accepts lowercase.","triggerScenarios":"create_from_litellm_data with row['model'] == \"\" (empty model produces an empty cloud_local_id); model metadata containing newlines/whitespace; calling create_from_components directly with service_type like 'LiteLLM'; any component collapsing to an empty string after normalization cannot be the cause (empty becomes 'unknown').","commonSituations":"Usage rows where model failed to populate (empty string instead of missing key — missing keys default to 'unknown'); upstream metadata with embedded newlines; teams reusing the generator for custom entities with capitalized service names.","solutions":["Guarantee a non-empty model: treat '' the same as missing (row.get('model') or 'unknown')","Pass service_type lowercase ('litellm'), since uppercase passes normalization but fails the regex","Strip whitespace/newlines from any value destined for cloud_local_id before generating","Catch ValueError per-row during export and log the offending row instead of aborting the whole batch"],"exampleFix":"# before\nmodel = row.get(\"model\", \"unknown\")   # row[\"model\"] == \"\" slips through\n\n# after\nmodel = (row.get(\"model\") or \"unknown\").strip() or \"unknown\"","handlingStrategy":"validation","validationCode":"def czrn_inputs_valid(service_type: str, cloud_local_id: str) -> bool:\n    return (\n        service_type == service_type.lower()\n        and bool(str(cloud_local_id).strip())\n        and \"\\n\" not in str(cloud_local_id)\n    )","typeGuard":null,"tryCatchPattern":"try:\n    czrn = generator.create_from_components(...)\nexcept ValueError as e:\n    log_error(f\"bad usage row, skipping: {e}\")  # quarantine the row, keep exporting the batch\n    continue","preventionTips":["Never pass an empty model — use (row.get('model') or 'unknown').strip() or 'unknown'","Keep service_type lowercase; normalization permits uppercase but the regex does not","Strip newlines/whitespace from anything destined for cloud_local_id","Quarantine malformed rows instead of letting one row abort the whole export"],"tags":["cloudzero","czrn","identifier-validation","usage-export"],"backgroundTag":"resource-id-validation-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}