Skip to content

node:perf_hooks: validate performance.measure name argument #3088

@andrewtdiz

Description

@andrewtdiz

Summary

performance.measure(name, ...) requires name to be a string in Node. Perry currently coerces name with the same String(value) behavior used by performance.mark(), so undefined, null, numbers, booleans, objects, arrays, and symbols can create measure entries instead of throwing.

Node behavior

Probe run with npx --yes node@25.9.0:

const { performance } = require("node:perf_hooks");
for (const value of [undefined, null, 0, true, {}, [], Symbol("s")]) {
  try {
    performance.measure(value);
    console.log(String(value), "no throw");
  } catch (err) {
    console.log(String(value), err.name, err.code || "no-code", err.message);
  }
}

Observed result: every non-string value throws TypeError [ERR_INVALID_ARG_TYPE] for the "name" argument. This differs from performance.mark(), which intentionally string-coerces non-symbol names.

Perry implementation evidence

  • crates/perry-runtime/src/perf_hooks.rs::js_perf_mark() explicitly checks symbols and otherwise calls coerce_to_string(name_val), matching Node mark-name coercion.
  • crates/perry-runtime/src/perf_hooks.rs::js_perf_measure() also starts with let name = coerce_to_string(name_val); and has no string-type validation or symbol-specific error path.
  • crates/perry-runtime/src/object/native_module_dispatch.rs routes ("perf_hooks", "measure") directly to js_perf_measure(arg(0), arg(1), arg(2)).
  • Existing perf_hooks fixtures cover valid measure names and option endpoint validation, but not invalid name types.

Expected fix

  • Validate that performance.measure() receives a string name before creating an entry.
  • Throw TypeError [ERR_INVALID_ARG_TYPE] for missing, null, primitive non-string, object, array, and symbol names.
  • Preserve the existing performance.mark() name coercion behavior.
  • Add parity coverage for invalid measure() name values and one control case showing mark(1).name === "1" still works.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions