BerriAI/litellm · error · ValueError

Generated CZRN is invalid: {czrn}

Error message

Generated CZRN is invalid: {czrn}

What it means

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.

Source

Thrown at litellm/integrations/cloudzero/cz_resource_names.py:96

        provider: str,
        region: str,
        owner_account_id: str,
        resource_type: str,
        cloud_local_id: str,
    ) -> str:
        """Create a CZRN from individual components."""
        # Normalize components to ensure they meet CZRN requirements
        service_type = self._normalize_component(service_type, allow_uppercase=True)
        provider = self._normalize_component(provider)
        region = self._normalize_component(region)
        owner_account_id = self._normalize_component(owner_account_id)
        resource_type = self._normalize_component(resource_type)
        # cloud_local_id can contain pipes and other characters, so don't normalize it

        czrn: Final = f"czrn:{service_type}:{provider}:{region}:{owner_account_id}:{resource_type}:{cloud_local_id}"

        if not self.is_valid(czrn):
            raise ValueError(f"Generated CZRN is invalid: {czrn}")

        return czrn

    def is_valid(self, czrn: str) -> bool:
        """Validate a CZRN string against the standard format."""
        return bool(self.CZRN_REGEX.match(czrn))

    def extract_components(self, czrn: str) -> tuple[str, str, str, str, str, str]:
        """Extract all components from a CZRN.

        Returns: (service_type, provider, region, owner_account_id, resource_type, cloud_local_id)
        """
        match: Final = self.CZRN_REGEX.match(czrn)
        if not match:
            raise ValueError(f"Invalid CZRN format: {czrn}")

        return cast(tuple[str, str, str, str, str, str], match.groups())

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Guarantee a non-empty model: treat '' the same as missing (row.get('model') or 'unknown')
  2. Pass service_type lowercase ('litellm'), since uppercase passes normalization but fails the regex
  3. Strip whitespace/newlines from any value destined for cloud_local_id before generating
  4. Catch ValueError per-row during export and log the offending row instead of aborting the whole batch

Example fix

# before
model = row.get("model", "unknown")   # row["model"] == "" slips through

# after
model = (row.get("model") or "unknown").strip() or "unknown"
Defensive patterns

Strategy: validation

Validate before calling

def czrn_inputs_valid(service_type: str, cloud_local_id: str) -> bool:
    return (
        service_type == service_type.lower()
        and bool(str(cloud_local_id).strip())
        and "\n" not in str(cloud_local_id)
    )

Try / catch

try:
    czrn = generator.create_from_components(...)
except ValueError as e:
    log_error(f"bad usage row, skipping: {e}")  # quarantine the row, keep exporting the batch
    continue

Prevention

When it happens

Trigger: 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').

Common situations: 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.

Related errors


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