denoland/deno · error · Error

Only valueType: DOUBLE is supported

Error message

Only valueType: DOUBLE is supported

What it means

Meter.createCounter() in Deno's OpenTelemetry shim (ext/telemetry/telemetry.ts:800) rejects options.valueType when present and not equal to 1. The file defines enum ValueType { INT = 0, DOUBLE = 1 }; only DOUBLE is supported because the OTLP exporter pipeline records all values as doubles. Passing ValueType.INT (0) or any other number throws before the instrument is created.

Source

Thrown at ext/telemetry/telemetry.ts:822

  }
}

const BATCH_CALLBACKS = new SafeMap<
  BatchObservableCallback,
  BatchObservableResult
>();
const INDIVIDUAL_CALLBACKS = new SafeMap<Observable, Set<ObservableCallback>>();

class Meter {
  #meter: OtelMeter;

  constructor(meter: OtelMeter) {
    this.#meter = meter;
  }

  createCounter(name: string, options?: MetricOptions): Counter {
    if (options?.valueType !== undefined && options?.valueType !== 1) {
      throw new Error("Only valueType: DOUBLE is supported");
    }
    if (!METRICS_ENABLED) return new Counter(null, false);
    const instrument = this.#meter.createCounter(
      name,
      // deno-lint-ignore deno-internal/prefer-primordials
      options?.description,
      options?.unit,
    ) as Instrument;
    return new Counter(instrument, false);
  }

  createUpDownCounter(name: string, options?: MetricOptions): Counter {
    if (options?.valueType !== undefined && options?.valueType !== 1) {
      throw new Error("Only valueType: DOUBLE is supported");
    }
    if (!METRICS_ENABLED) return new Counter(null, true);
    const instrument = this.#meter.createUpDownCounter(
      name,

View on GitHub (pinned to a961cdec3b)

Solutions

  1. Omit valueType from the options; it is optional and defaults to double behavior
  2. If you must be explicit, use ValueType.DOUBLE (1)
  3. Nothing else changes: JS numbers are recorded as doubles regardless, so integer counters can be replaced 1:1 by double counters

Example fix

// before
const counter = meter.createCounter('hits', { valueType: 0 }); // ValueType.INT

// after
const counter = meter.createCounter('hits'); // or { valueType: 1 }
Defensive patterns

Strategy: validation

Validate before calling

const opts = valueType === undefined || valueType === 1
  ? { valueType }
  : {}; // strip unsupported valueType before the call
const counter = meter.createCounter("hits", opts);

Type guard

function supportsValueType(
  o: { valueType?: number } | undefined,
): boolean {
  return o?.valueType === undefined || o?.valueType === 1;
}

Try / catch

try {
  counter = meter.createCounter(name, options);
} catch (e) {
  if (e instanceof Error && e.message === "Only valueType: DOUBLE is supported") {
    counter = meter.createCounter(name); // retry without options
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: meter.createCounter('hits', { valueType: ValueType.INT }); meter.createCounter('hits', { valueType: 0 }); reusing instrument options objects copied from an SDK-based app that used integer counters.

Common situations: Migrating metrics code from @opentelemetry/sdk-metrics where INT counters/gauges are valid; codegen that always emits valueType; using an enum imported from a mismatched OTel package version.

Related errors


AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20). Data as JSON: /api/errors/fe4e011883208bd5. Report an issue: GitHub.