{"record":{"id":"d1166c8d73b41a10","repo":"denoland/deno","slug":"options-cannot-be-passed-with-endmark","errorCode":null,"errorMessage":"Options cannot be passed with \"endMark\"","messagePattern":"Options cannot be passed with \"endMark\"","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/web/15_performance.js","lineNumber":754,"sourceCode":"    );\n\n    startOrMeasureOptions = webidl.converters\n      [\"DOMString or PerformanceMeasureOptions\"](\n        startOrMeasureOptions,\n        prefix,\n        \"Argument 2\",\n      );\n\n    if (endMark !== undefined) {\n      endMark = webidl.converters.DOMString(endMark, prefix, \"Argument 3\");\n    }\n\n    if (\n      startOrMeasureOptions && typeof startOrMeasureOptions === \"object\" &&\n      ObjectKeys(startOrMeasureOptions).length > 0\n    ) {\n      if (endMark) {\n        throw new TypeError('Options cannot be passed with \"endMark\"');\n      }\n      if (\n        ReflectHas(startOrMeasureOptions, \"start\") &&\n        ReflectHas(startOrMeasureOptions, \"duration\") &&\n        ReflectHas(startOrMeasureOptions, \"end\")\n      ) {\n        throw new TypeError(\n          'Cannot specify \"start\", \"end\", and \"duration\" together in options',\n        );\n      }\n    }\n    let endTime;\n    if (endMark) {\n      endTime = convertMarkToTimestamp(endMark);\n    } else if (\n      typeof startOrMeasureOptions === \"object\" &&\n      ReflectHas(startOrMeasureOptions, \"end\")\n    ) {","sourceCodeStart":736,"sourceCodeEnd":772,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/web/15_performance.js#L736-L772","documentation":"performance.measure(name, startOrMeasureOptions, endMark) has two mutually exclusive shapes: either a third-argument endMark string, or a second-argument options object describing start/end/duration. Deno throws a TypeError from ext/web/15_performance.js when the options object is a non-empty object AND an endMark string was also passed. The check only fires for real objects with at least one own key.","triggerScenarios":"performance.measure(\"m\", { start: 0 }, \"endMark\") — options plus a mark name; passing a default empty-ish options object that later gained keys; wrapper functions that accept both parameters and forward them unconditionally.","commonSituations":"Generalizing a measure() helper so it accepts options and endMark, then calling it with both; refactoring from the (startMark, endMark) form to the options form without removing the third argument; copy-pasting from mixed examples.","solutions":["Pick one shape: use endMark as argument 3 with at most a start mark/number as argument 2, or put everything in the options object.","To express start-to-end, prefer options: performance.measure(\"m\", { start: \"mark1\", end: \"mark2\" }).","If argument 2 is only a start mark name, that is fine with endMark — the conflict is only with a non-empty options object.","In wrapper functions, branch: if the caller supplied options, ignore/forbid endMark."],"exampleFix":"// before\nperformance.measure(\"m\", { start: \"a\" }, \"b\");\n\n// after\nperformance.measure(\"m\", { start: \"a\", end: \"b\" });","handlingStrategy":"validation","validationCode":"function measure(name, options, endMark) {\n  const hasOptions =\n    options != null && typeof options === \"object\" &&\n    Object.keys(options).length > 0;\n  if (hasOptions && endMark !== undefined) {\n    // move endMark into options instead of throwing\n    options = { ...options, end: endMark };\n    endMark = undefined;\n  }\n  return performance.measure(name, options, endMark);\n}","typeGuard":"function isMeasureOptions(v) {\n  return v != null && typeof v === \"object\" && !Array.isArray(v);\n}","tryCatchPattern":"try { performance.measure(n, opts, endMark); } catch (e) { if (e instanceof TypeError && e.message.includes(\"endMark\")) performance.measure(n, { ...opts, end: endMark }); else throw e; }","preventionTips":["In wrappers, choose one calling convention and document it.","Do not forward both parameters blindly from a generic helper.","Prefer the options object form for new code; it expresses everything endMark can."],"tags":["performance","performance-mark","web-api","typeerror"],"backgroundTag":"conflicting-options-parameters","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}