{"record":{"id":"b0583f3726b8c497","repo":"dotnet/runtime","slug":"count-or-values-must-be-either-an-array-or-a-numbe","errorCode":null,"errorMessage":"count_or_values must be either an array or a number greater than 0","messagePattern":"count_or_values must be either an array or a number greater than 0","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/roots.ts","lineNumber":114,"sourceCode":"/**\n * Allocates 1 or more temporary roots, accepting either a number of roots or an array of pointers.\n * mono_wasm_new_roots(n): returns an array of N zero-initialized roots.\n * mono_wasm_new_roots([a, b, ...]) returns an array of new roots initialized with each element.\n * Each root must be released with its release method, or using the mono_wasm_release_roots API.\n */\nexport function mono_wasm_new_roots<T extends MonoObject> (count_or_values: number | T[]): WasmRoot<T>[] {\n    let result;\n\n    if (Array.isArray(count_or_values)) {\n        result = new Array(count_or_values.length);\n        for (let i = 0; i < result.length; i++)\n            result[i] = mono_wasm_new_root(count_or_values[i]);\n    } else if ((count_or_values | 0) > 0) {\n        result = new Array(count_or_values);\n        for (let i = 0; i < result.length; i++)\n            result[i] = mono_wasm_new_root();\n    } else {\n        throw new Error(\"count_or_values must be either an array or a number greater than 0\");\n    }\n\n    return result;\n}\n\n/**\n * Releases 1 or more root or root buffer objects.\n * Multiple objects may be passed on the argument list.\n * 'undefined' may be passed as an argument so it is safe to call this method from finally blocks\n *  even if you are not sure all of your roots have been created yet.\n * @param {... WasmRoot} roots\n */\nexport function mono_wasm_release_roots (...args: WasmRoot<any>[]): void {\n    for (let i = 0; i < args.length; i++) {\n        if (is_nullish(args[i]))\n            continue;\n\n        args[i].release();","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/browser/runtime/roots.ts#L96-L132","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["If you want N roots, ensure N is a positive integer before calling.","If you want initialized roots, pass an array of numeric pointers.","Guard: branch on Array.isArray / Number.isInteger(x) && x > 0 at the call site and skip when nothing is needed."],"exampleFix":"// before\nconst roots = mono_wasm_new_roots(values.length); // throws if values is empty\n// after\nconst roots = values.length > 0 ? mono_wasm_new_roots(values.length) : [];","handlingStrategy":"type-guard","validationCode":"function newRootsSafe(count_or_values: number | unknown[]) {\n  if (Array.isArray(count_or_values)) return mono_wasm_new_roots(count_or_values);\n  if (typeof count_or_values === 'number' && Number.isInteger(count_or_values) && count_or_values > 0)\n    return mono_wasm_new_roots(count_or_values);\n  return [];\n}","typeGuard":"function isRootsArg(a: unknown): a is number | unknown[] {\n  return Array.isArray(a) || (typeof a === 'number' && Number.isInteger(a) && a > 0);\n}","tryCatchPattern":null,"preventionTips":["Handle the empty-count case in the caller instead of forwarding 0.","Use Array.isArray plus Number.isInteger checks at the boundary.","Avoid floats - they truncate to 0 via |0 and silently fail."],"tags":["gc-roots","validation","argument-error","typescript"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}