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
- Omit valueType from the options; it is optional and defaults to double behavior
- If you must be explicit, use ValueType.DOUBLE (1)
- 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
- Never set valueType; omit it unless you explicitly pass 1 (DOUBLE)
- Centralize instrument creation in one factory so the rule is encoded once
- When migrating from the OTel SDK, strip valueType: INT from every instrument config
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
- MeterProvider can not be constructed
- startActiveSpan requires a function argument
- ContextManager can not be constructed
- Counter can only be incremented
- Observable counters can only be incremented
AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20).
Data as JSON: /api/errors/fe4e011883208bd5.
Report an issue: GitHub.