microsoft/aspire · error

Metric data point has no value.

Error message

Metric data point has no value.

What it means

An OTLP NumberDataPoint must carry a value in either the AsInt or AsDouble oneof case. AddNumberMetricPoint validates the point and throws InvalidOperationException when neither is set, because the repository cannot determine whether to store a long or double value.

Solutions

  1. Fix the emitter/exporter to always set either AsInt or AsDouble on number data points.
  2. Check any OTel Collector processors/config that may be stripping point values.
  3. Validate the OTLP payload before export (e.g. with protoc or a validation processor).
  4. If the payload is generated in tests, populate .AsInt or .AsDouble explicitly.

Example fix

// before
var point = new NumberDataPoint { TimeUnixNano = now };
// after
var point = new NumberDataPoint { TimeUnixNano = now, AsDouble = 1.0 };
Defensive patterns

Strategy: validation

Validate before calling

if (point.ValueCase is not (NumberDataPoint.ValueOneofCase.AsInt or NumberDataPoint.ValueOneofCase.AsDouble))
    throw new InvalidOperationException("NumberDataPoint must set AsInt or AsDouble.");

Type guard

static bool HasValue(NumberDataPoint p) =>
    p.ValueCase is NumberDataPoint.ValueOneofCase.AsInt or NumberDataPoint.ValueOneofCase.AsDouble;

Try / catch

try
{
    await repo.AddMetricsAsync(request);
}
catch (InvalidOperationException ex) when (ex.Message == "Metric data point has no value.")
{
    logger.LogWarning(ex, "Dropping malformed number data point.");
}

Prevention

When it happens

Trigger: AddMetricToDatabase -> AddNumberMetricPoint receives a NumberDataPoint whose ValueCase is neither AsInt nor AsDouble (value oneof unset).

Common situations: A custom exporter or hand-built OTLP protobuf omits as_int/as_double; a collector transformation drops the value field; a buggy instrumentation library serializes empty data points.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/306a32849ef72c88. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Dashboard/Otlp/Storage/SqliteTelemetryRepository.Metrics.Writes.cs:182

    }

    private void AddNumberMetricPoint(
        SqliteConnection connection,
        IDbTransaction transaction,
        AddContext context,
        long instrumentId,
        NumberDataPoint point,
        MetricIngestionState ingestionState,
        MetricPointBatch pointBatch)
    {
        try
        {
            OtlpHelpers.ValidateNumberDataPoint(point);
            var pointType = point.ValueCase switch
            {
                NumberDataPoint.ValueOneofCase.AsInt => LongPointType,
                NumberDataPoint.ValueOneofCase.AsDouble => DoublePointType,
                _ => throw new InvalidOperationException("Metric data point has no value.")
            };
            var dimension = GetOrAddMetricDimension(connection, transaction, instrumentId, point.Attributes, ingestionState);
            var pendingLatest = dimension.PendingPoint;
            var latest = dimension.LatestPoint;
            var latestPointType = pendingLatest?.PointType ?? latest?.PointType;
            var latestEndTimeTicks = pendingLatest?.EndTimeTicks ?? latest?.EndTimeTicks;
            var sameValue = latestPointType == pointType && (pendingLatest is not null
                ? pointType == LongPointType ? pendingLatest.IntegerValue == point.AsInt : pendingLatest.DoubleValue == point.AsDouble
                : pointType == LongPointType ? latest?.IntegerValue == point.AsInt : latest?.DoubleValue == point.AsDouble);
            var endTimeTicks = OtlpHelpers.UnixNanoSecondsToDateTime(point.TimeUnixNano).Ticks;
            if (sameValue)
            {
                if (pendingLatest is not null)
                {
                    pendingLatest.EndTimeTicks = endTimeTicks;
                    pendingLatest.RepeatCount++;
                    pendingLatest.SourcePointCount++;
                    pendingLatest.Exemplars.AddRange(point.Exemplars);

View on GitHub (pinned to 25830f84bd)