{"record":{"id":"79f69ae8c74fb579","repo":"influxdata/influxdb","slug":"key-type-key-key-cannot-contain-equals-signs","errorCode":null,"errorMessage":"{key_type} key '{key}' cannot contain equals signs","messagePattern":"(.+?) key '(.+?)' cannot contain equals signs","errorType":"validation","errorClass":"InvalidKeyError","httpStatus":null,"severity":"error","filePath":"influxdb3_py_api/src/line_builder/line_builder.py","lineNumber":47,"sourceCode":"class LineBuilder:\n    def __init__(self, measurement: str):\n        if \" \" in measurement:\n            raise InvalidMeasurementError(\"Measurement name cannot contain spaces\")\n        self.measurement = measurement\n        self.tags: OrderedDict[str, str] = OrderedDict()\n        self.fields: OrderedDict[str, str] = OrderedDict()\n        self._timestamp_ns: Optional[int] = None\n\n    def _validate_key(self, key: str, key_type: str) -> None:\n        \"\"\"Validate that a key does not contain spaces, commas, or equals signs.\"\"\"\n        if not key:\n            raise InvalidKeyError(f\"{key_type} key cannot be empty\")\n        if \" \" in key:\n            raise InvalidKeyError(f\"{key_type} key '{key}' cannot contain spaces\")\n        if \",\" in key:\n            raise InvalidKeyError(f\"{key_type} key '{key}' cannot contain commas\")\n        if \"=\" in key:\n            raise InvalidKeyError(f\"{key_type} key '{key}' cannot contain equals signs\")\n\n    def _escape_measurement(self, value: str) -> str:\n        \"\"\"Escape characters in measurement names according to line protocol.\"\"\"\n        return value.replace(\",\", \"\\\\,\").replace(\" \", \"\\\\ \")\n\n    def _escape_tag_value(self, value: str) -> str:\n        \"\"\"Escape characters in tag values according to line protocol.\"\"\"\n        return (\n            value.replace(\"\\\\\", \"\\\\\\\\\")\n            .replace(\",\", \"\\\\,\")\n            .replace(\"=\", \"\\\\=\")\n            .replace(\" \", \"\\\\ \")\n        )\n\n    def _escape_field_key(self, value: str) -> str:\n        \"\"\"Escape characters in field keys according to line protocol.\"\"\"\n        return (\n            value.replace(\"\\\\\", \"\\\\\\\\\")","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/influxdata/influxdb/blob/d28e26e048401c53cbb98cf2d6ab0cf1e98048ca/influxdb3_py_api/src/line_builder/line_builder.py#L29-L65","documentation":"LineBuilder._validate_key raises InvalidKeyError when a tag or field key contains an equals sign. '=' separates keys from values in line protocol tag/field pairs, so an '=' inside an identifier makes parsing ambiguous; the builder rejects it. Tag values and field values containing '=' are fine because they are escaped automatically.","triggerScenarios":"builder.tag('a=b', 'x') — most often the caller parsed a 'key=value' string but passed the whole unsplit token as the key, or an f-string key accidentally includes '=' (e.g. f'{k}={v}').","commonSituations":"Handling 'k=v' config/metric strings from env files, log lines, or query strings where split('=') was skipped or applied to the wrong variable.","solutions":["Split the token on the first '=' and use only the left side as the key","Fix the f-string that embeds '=' into a key name","Run keys through a sanitizer that strips ' ', ',', '=' before the builder call"],"exampleFix":"# before\nbuilder.tag(raw_token, \"x\")  # raw_token == 'a=b' -> InvalidKeyError\n\n# after\nkey, _, value = raw_token.partition(\"=\")\nbuilder.tag(key, value or \"x\")","handlingStrategy":"validation","validationCode":"def split_kv(token: str) -> tuple[str, str]:\n    key, sep, value = token.partition(\"=\")\n    if not sep or not key:\n        raise ValueError(f\"expected key=value, got {token!r}\")\n    return key, value","typeGuard":null,"tryCatchPattern":"from influxdb3_py_api.line_builder import InvalidKeyError\n\ntry:\n    builder.tag(key, value)\nexcept InvalidKeyError as e:\n    logger.warning(\"bad key: %s\", e)","preventionTips":["Parse 'k=v' strings with partition('=') and use only the left side as a key","Never interpolate '=' into identifier names via f-strings","Sanitize external identifiers before they reach the builder"],"tags":["influxdb","line-protocol","python","tags","fields","validation"],"backgroundTag":"line-protocol-validation","analyzedSha":"d28e26e048401c53cbb98cf2d6ab0cf1e98048ca","analyzedAt":"2026-08-16T19:53:34.623Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}