dotnet/runtime · error · Error

count_or_values must be either an array or a number greater

Error message

count_or_values must be either an array or a number greater than 0

What it means

Thrown by mono_wasm_new_roots when count_or_values is neither an array nor a positive integer. The API accepts either an array of pointers (initializing one root each) or a count (allocating that many zero roots); anything else - zero, negative, NaN, object, string - falls through to the error branch at line 114.

Source

Thrown at src/mono/browser/runtime/roots.ts:114

/**
 * Allocates 1 or more temporary roots, accepting either a number of roots or an array of pointers.
 * mono_wasm_new_roots(n): returns an array of N zero-initialized roots.
 * mono_wasm_new_roots([a, b, ...]) returns an array of new roots initialized with each element.
 * Each root must be released with its release method, or using the mono_wasm_release_roots API.
 */
export function mono_wasm_new_roots<T extends MonoObject> (count_or_values: number | T[]): WasmRoot<T>[] {
    let result;

    if (Array.isArray(count_or_values)) {
        result = new Array(count_or_values.length);
        for (let i = 0; i < result.length; i++)
            result[i] = mono_wasm_new_root(count_or_values[i]);
    } else if ((count_or_values | 0) > 0) {
        result = new Array(count_or_values);
        for (let i = 0; i < result.length; i++)
            result[i] = mono_wasm_new_root();
    } else {
        throw new Error("count_or_values must be either an array or a number greater than 0");
    }

    return result;
}

/**
 * Releases 1 or more root or root buffer objects.
 * Multiple objects may be passed on the argument list.
 * 'undefined' may be passed as an argument so it is safe to call this method from finally blocks
 *  even if you are not sure all of your roots have been created yet.
 * @param {... WasmRoot} roots
 */
export function mono_wasm_release_roots (...args: WasmRoot<any>[]): void {
    for (let i = 0; i < args.length; i++) {
        if (is_nullish(args[i]))
            continue;

        args[i].release();

View on GitHub (pinned to 60108ba66e)

Solutions

  1. If you want N roots, ensure N is a positive integer before calling.
  2. If you want initialized roots, pass an array of numeric pointers.
  3. Guard: branch on Array.isArray / Number.isInteger(x) && x > 0 at the call site and skip when nothing is needed.

Example fix

// before
const roots = mono_wasm_new_roots(values.length); // throws if values is empty
// after
const roots = values.length > 0 ? mono_wasm_new_roots(values.length) : [];
Defensive patterns

Strategy: type-guard

Validate before calling

function newRootsSafe(count_or_values: number | unknown[]) {
  if (Array.isArray(count_or_values)) return mono_wasm_new_roots(count_or_values);
  if (typeof count_or_values === 'number' && Number.isInteger(count_or_values) && count_or_values > 0)
    return mono_wasm_new_roots(count_or_values);
  return [];
}

Type guard

function isRootsArg(a: unknown): a is number | unknown[] {
  return Array.isArray(a) || (typeof a === 'number' && Number.isInteger(a) && a > 0);
}

Prevention

When it happens

Trigger: Calling mono_wasm_new_roots(0), mono_wasm_new_roots(-3), mono_wasm_new_roots(NaN), or mono_wasm_new_roots(someObject) (non-array, non-number). Note (count_or_values | 0) > 0 means fractional/zero values fail.

Common situations: Passing a length computed from an empty collection; passing a JS object instead of an array; passing a float that truncates to 0 via |0; a variable that is sometimes undefined.

Related errors


AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10). Data as JSON: /api/errors/b0583f3726b8c497. Report an issue: GitHub.