netdata/netdata · error · ValueError

Invalid description for {integration_id}: must be a string:

Error message

Invalid description for {integration_id}: must be a string: {value!r}

What it means

metrix reserves one label key (SummaryQuantileLabel) to flatten summary quantiles into dimensions. The library panics when a caller-supplied LabelSet contains that reserved key, because at flatten time the generated quantile dimension label would collide with the user's label and make series identity ambiguous.

Source

Thrown at integrations/descriptions.py:238

    return normalize_description(paragraph, summarize=True)


def get_description_override(integration: Dict[str, Any]) -> Optional[str]:
    """Return the exact explicit metadata description, if present and valid."""
    integration_id = integration.get("id", _MISSING_ID)
    meta = integration.get("meta", {})
    if not isinstance(meta, dict):
        raise ValueError(
            f"Invalid description for {integration_id}: meta must be a mapping: {meta!r}"
        )
    monitored_instance = meta.get("monitored_instance")
    owner = monitored_instance if isinstance(monitored_instance, dict) else meta
    if not isinstance(owner, dict) or "description" not in owner:
        return None

    value = owner["description"]
    if not isinstance(value, str):
        raise ValueError(f"Invalid description for {integration_id}: must be a string: {value!r}")

    validate_description(value, integration_id)
    return value


def validate_description(description: str, integration_id: str) -> None:
    if not isinstance(description, str):
        raise ValueError(f"Invalid description for {integration_id}: must be a string: {description!r}")

    errors = []
    length = len(description)

    if length < MIN_DESCRIPTION_LENGTH or length > MAX_DESCRIPTION_LENGTH:
        errors.append(
            f"length {length} is outside {MIN_DESCRIPTION_LENGTH}-{MAX_DESCRIPTION_LENGTH} characters"
        )
    if description != description.strip():
        errors.append("contains leading or trailing whitespace")

View on GitHub (pinned to 4864de85e2)

Solutions

  1. Rename your label to something else (e.g. 'q' or 'fractile') so it cannot collide with the reserved quantile key.
  2. Strip/whitelist external labels before forwarding them into a metrix summary instrument.
  3. Check the constant SummaryQuantileLabel in the metrix package and treat it as a namespace reserved by the framework.

Example fix

// before
summary.Record(point, metrix.Label("quantile", ver)) // reserved key

// after
summary.Record(point, metrix.Label("q_version", ver))
Defensive patterns

Strategy: validation

Validate before calling

func safeLabels(ls []metrix.LabelSet) []metrix.LabelSet {
    for _, s := range ls {
        if s.Has(metrix.SummaryQuantileLabel) { return nil /* skip write */ }
    }
    return ls
}

Prevention

When it happens

Trigger: Passing a LabelSet (via instrument base labels or per-call labels) whose key equals SummaryQuantileLabel to a summary Record API; the check labelsContainKey(labels, SummaryQuantileLabel) trips inside the locked record path.

Common situations: Copying a Prometheus/OpenMetrics exemplar or histogram code path that already carries a 'quantile' label; renaming labels during a collector refactor and accidentally matching the reserved key; generic pass-through of exporter-provided labels.

Related errors


AI-assisted analysis of netdata/netdata@4864de85e2 (2026-08-15). Data as JSON: /api/errors/96383030d9bd381d. Report an issue: GitHub.