{"record":{"id":"f2fdb97be1c957e6","repo":"influxdata/influxdb","slug":"key-type-key-cannot-be-empty","errorCode":null,"errorMessage":"{key_type} key cannot be empty","messagePattern":"(.+?) key cannot be empty","errorType":"exception","errorClass":"InvalidKeyError","httpStatus":null,"severity":"error","filePath":"influxdb3_py_api/src/line_builder/line_builder.py","lineNumber":41,"sourceCode":"class InvalidLineError(InfluxDBError):\n    \"\"\"Raised when a line protocol string is invalid\"\"\"\n\n    pass\n\n\nclass 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(\" \", \"\\\\ \")","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_py_api/src/line_builder/line_builder.py#L23-L59","documentation":"LineBuilder._validate_key enforces that tag keys and field keys are non-empty and free of spaces, commas, and equals signs, since those characters are line-protocol delimiters and would corrupt the generated point. The first check raises InvalidKeyError with '{key_type} key cannot be empty' when an empty string is passed as a tag or field key.","triggerScenarios":"Calling lb.tag(\"\", \"v\") or any field setter (uint64_field/int64_field/float64_field/string_field/bool_field) with an empty key string — typically when the key comes from a dict lookup, split result, or variable that ends up as ''.","commonSituations":"Dynamic tag/field names built from parsed input where a segment is missing (e.g. 'cpu,=val'.split(',') behavior, dict.get returning ''), or configuration entries with blank names.","solutions":["Check key length before calling the setter and skip/error on empty keys.","Fix the source of the empty name (bad split, missing dict entry, blank config value).","Provide a default key name when the dynamic key is unavailable."],"exampleFix":"# before\nfor k, v in tags.items():\n    lb.tag(k, v)\n# after\nfor k, v in tags.items():\n    if not k:\n        continue\n    lb.tag(k, v)","handlingStrategy":"validation","validationCode":"def safe_tag(lb, key: str, value: str):\n    if not isinstance(key, str) or not key:\n        raise ValueError(\"tag key must be a non-empty string\")\n    lb.tag(key, value)","typeGuard":"def is_valid_key(k) -> bool:\n    return isinstance(k, str) and len(k) > 0 and not any(c in k for c in \" ,=\")","tryCatchPattern":"try:\n    lb.tag(key, value)\nexcept InvalidKeyError as e:\n    log.warning(f\"skipping invalid key: {e}\")","preventionTips":["Filter empty keys before iterating tags/fields dicts","Guard dict.get / split results that may yield empty strings","Enforce non-blank key names in configs and CSV headers","Centralize key construction in one validated helper"],"tags":["python","sdk","line-protocol","validation"],"backgroundTag":"empty-required-field","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}