{"record":{"id":"5f7b7922d2ee36c8","repo":"influxdata/influxdb","slug":"at-least-one-field-is-required-line","errorCode":null,"errorMessage":"At least one field is required: {line}","messagePattern":"At least one field is required: (.+?)","errorType":"validation","errorClass":"InvalidLineError","httpStatus":null,"severity":"error","filePath":"influxdb3_py_api/src/line_builder/line_builder.py","lineNumber":132,"sourceCode":"        self._timestamp_ns = timestamp_ns\n        return self\n\n    def build(self) -> str:\n        \"\"\"Build the line protocol string.\"\"\"\n        # Start with measurement name (escape commas and spaces)\n        line = self._escape_measurement(self.measurement)\n\n        # Add tags if present\n        if self.tags:\n            tags_str = \",\".join(\n                f\"{key}={self._escape_tag_value(value)}\"\n                for key, value in self.tags.items()\n            )\n            line += f\",{tags_str}\"\n\n        # Add fields (required)\n        if not self.fields:\n            raise InvalidLineError(f\"At least one field is required: {line}\")\n\n        fields_str = \",\".join(\n            f\"{self._escape_field_key(key)}={value}\"\n            for key, value in self.fields.items()\n        )\n        line += f\" {fields_str}\"\n\n        # Add timestamp if present\n        if self._timestamp_ns is not None:\n            line += f\" {self._timestamp_ns}\"\n\n        return line\n","sourceCodeStart":114,"sourceCodeEnd":145,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_py_api/src/line_builder/line_builder.py#L114-L145","documentation":"InfluxDB line protocol requires at least one field on every line; tags alone are not a valid data point. build() checks the accumulated fields and raises InvalidLineError if none were added. This is a builder-state validation, not a per-call check, so it surfaces only at build time.","triggerScenarios":"Creating LineBuilder, adding only tag() calls (or none at all), then calling build(); conditionally adding fields with all conditions false.","commonSituations":"Code paths where field extraction fails silently and no fields are added; templated ingestion where a schema maps columns to fields but the column list is empty; users assuming tags alone form a valid point.","solutions":["Ensure at least one field is added before build(), e.g. always call string_field/float64_field with a default value.","Check `if not builder.fields: ...` or track field count before calling build().","Fix the upstream logic that skipped field population (e.g. missing column, failed parse)."],"exampleFix":"// before\nbuilder.measurement(\"cpu\").tag(\"host\", \"a\")\nline = builder.build()  # raises\n// after\nbuilder.measurement(\"cpu\").tag(\"host\", \"a\").float64_field(\"usage\", 0.0)\nline = builder.build()","handlingStrategy":"validation","validationCode":"if not builder.fields:\n    builder.float64_field('value', 0.0)  # or skip the point entirely","typeGuard":null,"tryCatchPattern":"try:\n    line = builder.build()\nexcept InvalidLineError:\n    logger.warning('skipping point with no fields')\n    line = None","preventionTips":["Never emit tag-only points; ensure every code path adds at least one field.","Track field population when fields are added conditionally.","Fail fast after field extraction: if no fields parsed, skip the record before building."],"tags":["validation","line-protocol","python","influxdb"],"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"}