zhisheng17/flink-learning · error · RuntimeException
No measurement defined
Error message
No measurement defined
What it means
InfluxDBSink.invoke uses the MetricEvent name as the InfluxDB measurement. If the event's name is null or whitespace, the sink throws RuntimeException('No measurement defined') because a Point cannot be written without a measurement.
Source
Thrown at flink-learning-connectors/flink-learning-connectors-influxdb/src/main/java/com/zhisheng/connectors/influxdb/InfluxDBSink.java:60
throw new RuntimeException("This " + influxDBConfig.getDatabase() + " database does not exist!");
}
}
influxDBClient.setDatabase(influxDBConfig.getDatabase());
if (influxDBConfig.getBatchActions() > 0) {
influxDBClient.enableBatch(influxDBConfig.getBatchActions(), influxDBConfig.getFlushDuration(), influxDBConfig.getFlushDurationTimeUnit());
}
if (influxDBConfig.isEnableGzip()) {
influxDBClient.enableGzip();
}
}
@Override
public void invoke(MetricEvent metricEvent, Context context) throws Exception {
if (StringUtils.isNullOrWhitespaceOnly(metricEvent.getName())) {
throw new RuntimeException("No measurement defined");
}
Point.Builder builder = Point.measurement(metricEvent.getName())
.time(metricEvent.getTimestamp(), TimeUnit.MILLISECONDS);
if (!CollectionUtil.isNullOrEmpty(metricEvent.getFields())) {
builder.fields(metricEvent.getFields());
}
if (!CollectionUtil.isNullOrEmpty(metricEvent.getTags())) {
builder.tag(metricEvent.getTags());
}
Point point = builder.build();
influxDBClient.write(point);
}
@OverrideView on GitHub (pinned to d731cee761)
Solutions
- Set metricEvent.name when constructing every MetricEvent before sinking
- Filter out events with blank names before adding them to the sink
- Add validation at the event-producing code so bad events fail at the source
Example fix
// before
MetricEvent e = new MetricEvent(null, fields, System.currentTimeMillis());
// after
MetricEvent e = new MetricEvent("cpu_usage", fields, System.currentTimeMillis()); Defensive patterns
Strategy: validation
Validate before calling
if (event == null || event.getName() == null || event.getName().trim().isEmpty()) {
return; // skip or log-and-drop before sinking
} Type guard
boolean hasMeasurement(MetricEvent e) {
return e != null && e.getName() != null && !e.getName().trim().isEmpty();
} Try / catch
try {
sink.invoke(metricEvent, context);
} catch (RuntimeException e) {
if ("No measurement defined".equals(e.getMessage())) {
LOG.warn("Dropping metric event without name: {}", metricEvent);
} else throw e;
} Prevention
- Enforce non-null names in the MetricEvent constructor/builder
- Filter or dead-letter events missing names upstream of the sink
- Add a unit test that every emitted MetricEvent has a name
When it happens
Trigger: Stream processing emits a MetricEvent whose getName() is null or blank (e.g. metric not set when building the event) and it reaches invoke().
Common situations: Upstream transformation steps that forgot to set the metric name, events deserialized from topics with missing fields, or filter/branch logic passing placeholder events through.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- This ${database} database does not exist!
- invalid elasticsearch hosts format
- invalid elasticsearch hosts format
- Unsupported client type - cannot happen
- Unknown value for CONSUMER_OFFSET_RESET_TO.
AI-assisted analysis of zhisheng17/flink-learning@d731cee761 (2026-09-06).
Data as JSON: /api/errors/f412ade2d28140da.
Report an issue: GitHub.