{"record":{"id":"96383030d9bd381d","repo":"netdata/netdata","slug":"invalid-description-for-integration-id-must-be","errorCode":null,"errorMessage":"Invalid description for {integration_id}: must be a string: {value!r}","messagePattern":"Invalid description for (.+?): must be a string: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"integrations/descriptions.py","lineNumber":238,"sourceCode":"    return normalize_description(paragraph, summarize=True)\n\n\ndef get_description_override(integration: Dict[str, Any]) -> Optional[str]:\n    \"\"\"Return the exact explicit metadata description, if present and valid.\"\"\"\n    integration_id = integration.get(\"id\", _MISSING_ID)\n    meta = integration.get(\"meta\", {})\n    if not isinstance(meta, dict):\n        raise ValueError(\n            f\"Invalid description for {integration_id}: meta must be a mapping: {meta!r}\"\n        )\n    monitored_instance = meta.get(\"monitored_instance\")\n    owner = monitored_instance if isinstance(monitored_instance, dict) else meta\n    if not isinstance(owner, dict) or \"description\" not in owner:\n        return None\n\n    value = owner[\"description\"]\n    if not isinstance(value, str):\n        raise ValueError(f\"Invalid description for {integration_id}: must be a string: {value!r}\")\n\n    validate_description(value, integration_id)\n    return value\n\n\ndef validate_description(description: str, integration_id: str) -> None:\n    if not isinstance(description, str):\n        raise ValueError(f\"Invalid description for {integration_id}: must be a string: {description!r}\")\n\n    errors = []\n    length = len(description)\n\n    if length < MIN_DESCRIPTION_LENGTH or length > MAX_DESCRIPTION_LENGTH:\n        errors.append(\n            f\"length {length} is outside {MIN_DESCRIPTION_LENGTH}-{MAX_DESCRIPTION_LENGTH} characters\"\n        )\n    if description != description.strip():\n        errors.append(\"contains leading or trailing whitespace\")","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/netdata/netdata/blob/4864de85e26f6734d92cfc27ccbeff5921f49938/integrations/descriptions.py#L220-L256","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Rename your label to something else (e.g. 'q' or 'fractile') so it cannot collide with the reserved quantile key.","Strip/whitelist external labels before forwarding them into a metrix summary instrument.","Check the constant SummaryQuantileLabel in the metrix package and treat it as a namespace reserved by the framework."],"exampleFix":"// before\nsummary.Record(point, metrix.Label(\"quantile\", ver)) // reserved key\n\n// after\nsummary.Record(point, metrix.Label(\"q_version\", ver))","handlingStrategy":"validation","validationCode":"func safeLabels(ls []metrix.LabelSet) []metrix.LabelSet {\n    for _, s := range ls {\n        if s.Has(metrix.SummaryQuantileLabel) { return nil /* skip write */ }\n    }\n    return ls\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat SummaryQuantileLabel as framework-reserved; never emit it from collector code.","When forwarding external labels, filter through an allowlist rather than passing them through."],"tags":["metrix","netdata","go","panic","labels"],"backgroundTag":null,"analyzedSha":"4864de85e26f6734d92cfc27ccbeff5921f49938","analyzedAt":"2026-08-15T09:12:38.226Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}