denoland/deno · error · TypeError

Cannot specify "start", "end", and "duration" together in op

Error message

Cannot specify "start", "end", and "duration" together in options

What it means

In performance.measure()'s options object, the timestamps "start", "end", and "duration" over-determine the measurement — any two imply the third. The spec therefore forbids supplying all three at once, and Deno throws this TypeError from ext/web/15_performance.js when Reflect.has finds all three keys present (even if a value is undefined). Remove one key and let the API derive it.

Source

Thrown at ext/web/15_performance.js:761

      );

    if (endMark !== undefined) {
      endMark = webidl.converters.DOMString(endMark, prefix, "Argument 3");
    }

    if (
      startOrMeasureOptions && typeof startOrMeasureOptions === "object" &&
      ObjectKeys(startOrMeasureOptions).length > 0
    ) {
      if (endMark) {
        throw new TypeError('Options cannot be passed with "endMark"');
      }
      if (
        ReflectHas(startOrMeasureOptions, "start") &&
        ReflectHas(startOrMeasureOptions, "duration") &&
        ReflectHas(startOrMeasureOptions, "end")
      ) {
        throw new TypeError(
          'Cannot specify "start", "end", and "duration" together in options',
        );
      }
    }
    let endTime;
    if (endMark) {
      endTime = convertMarkToTimestamp(endMark);
    } else if (
      typeof startOrMeasureOptions === "object" &&
      ReflectHas(startOrMeasureOptions, "end")
    ) {
      endTime = convertMarkToTimestamp(startOrMeasureOptions.end);
    } else if (
      typeof startOrMeasureOptions === "object" &&
      ReflectHas(startOrMeasureOptions, "start") &&
      ReflectHas(startOrMeasureOptions, "duration")
    ) {
      const start = convertMarkToTimestamp(startOrMeasureOptions.start);

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Delete one of the three keys — typically duration, since it equals end minus start.
  2. Audit spreads of default option objects and remove keys that callers also set.
  3. If the value for a key is unknown, omit the key entirely rather than setting it to undefined.
  4. Validate measure options with your own check: at most two of start/end/duration present.

Example fix

// before
performance.measure("m", { start: 0, end: 100, duration: 100 });

// after
performance.measure("m", { start: 0, end: 100 });
Defensive patterns

Strategy: validation

Validate before calling

function normalizeMeasure(o) {
  const keys = ["start", "end", "duration"];
  if (keys.every((k) => k in o)) delete o.duration; // derivable
  return o;
}
performance.measure("m", normalizeMeasure(opts));

Type guard

function hasAllThreeTimestamps(o) {
  return "start" in o && "end" in o && "duration" in o;
}

Try / catch

try { performance.measure(n, opts); } catch (e) { if (e instanceof TypeError && e.message.includes('"duration"')) { delete opts.duration; performance.measure(n, opts); } else throw e; }

Prevention

When it happens

Trigger: performance.measure("m", { start: 0, end: 100, duration: 100 }); options built by merging a defaults object containing all keys with caller overrides; a duration computed as end-start and then also passing start and end.

Common situations: Spreading `{ start: 0, end: 0, duration: 0 }` defaults into every measure call; autogenerated options from a benchmarking framework that fills all fields; keys present with undefined values still trigger the check because it uses key presence, not value.

Related errors


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