{"record":{"id":"9d9fd3e272359e5a","repo":"mastra-ai/mastra","slug":"maxretainedbytes-must-be-a-non-negative-integer-or","errorCode":null,"errorMessage":"maxRetainedBytes must be a non-negative integer or Infinity","messagePattern":"maxRetainedBytes must be a non-negative integer or Infinity","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/workspace/sandbox/process-manager/process-handle.ts","lineNumber":22,"sourceCode":" * Abstract base class for process handles.\n * Manages stdout/stderr callback dispatch and provides lazy\n * reader/writer stream getters — subclasses only implement\n * the platform-specific primitives.\n */\n\nimport { Readable, Writable } from 'node:stream';\n\nimport type { CommandResult } from '../types';\nimport type { SpawnProcessOptions } from './types';\n\nexport const DEFAULT_MAX_RETAINED_PROCESS_OUTPUT_BYTES = 1024 * 1024;\nconst RETAINED_OUTPUT_COMPACT_CHUNK_THRESHOLD = 128;\n\n/** @internal */\nexport function validateMaxRetainedProcessOutputBytes(maxRetainedBytes: number): number {\n  if (maxRetainedBytes === Infinity) return maxRetainedBytes;\n  if (!Number.isFinite(maxRetainedBytes) || maxRetainedBytes < 0 || !Number.isInteger(maxRetainedBytes)) {\n    throw new RangeError('maxRetainedBytes must be a non-negative integer or Infinity');\n  }\n  return maxRetainedBytes;\n}\n\nfunction advanceStartByUtf8Bytes(\n  value: string,\n  start: number,\n  minimumBytesToDrop: number,\n): { start: number; droppedBytes: number } {\n  let nextStart = start;\n  let droppedBytes = 0;\n\n  while (nextStart < value.length && droppedBytes < minimumBytesToDrop) {\n    const codePoint = value.codePointAt(nextStart)!;\n\n    if (codePoint < 0x80) droppedBytes += 1;\n    else if (codePoint < 0x800) droppedBytes += 2;\n    else if (codePoint < 0x10000) droppedBytes += 3;","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workspace/sandbox/process-manager/process-handle.ts#L4-L40","documentation":"validateMaxRetainedProcessOutputBytes enforces that maxRetainedProcessOutputBytes is a non-negative integer or Infinity. Any NaN, fractional, negative, or non-numeric value (other than Infinity) throws this RangeError at ProcessHandle construction.","triggerScenarios":"Constructing a ProcessHandle (or passing a process option) with e.g. maxRetainedBytes: -1, 10.5, '1MB', NaN, or null.","commonSituations":"Parsing a config value from env/CLI as a string instead of a number; computing a byte limit with arithmetic that yields a float (e.g. bytes = 0.5 * MB); typos like `1024 * 1024,` producing a non-integer expression result.","solutions":["Pass a non-negative integer (e.g. 5 * 1024 * 1024) or Infinity.","Coerce string config values with Number()/parseInt before passing.","Round computed limits with Math.floor()."],"exampleFix":"// before\nnew ProcessHandle({ maxRetainedProcessOutputBytes: opts.retainedOutput }); // '5242880' string\n// after\nconst n = Number(opts.retainedOutput);\nnew ProcessHandle({\n  maxRetainedProcessOutputBytes: Number.isFinite(n) ? Math.max(0, Math.floor(n)) : Infinity,\n});","handlingStrategy":"validation","validationCode":"function isValidRetainedBytes(v: unknown): v is number {\n  return v === Infinity || (typeof v === 'number' && Number.isInteger(v) && v >= 0);\n}\nif (!isValidRetainedBytes(opts.maxRetainedProcessOutputBytes)) {\n  throw new TypeError('maxRetainedProcessOutputBytes must be a non-negative integer or Infinity');\n}","typeGuard":"function isNonNegIntOrInfinity(v: unknown): v is number {\n  return v === Infinity || (typeof v === 'number' && Number.isSafeInteger(v) && v >= 0);\n}","tryCatchPattern":"try {\n  handle = new ProcessHandle({ maxRetainedProcessOutputBytes: raw });\n} catch (e) {\n  if (e instanceof RangeError && /maxRetainedBytes/.test(e.message)) {\n    handle = new ProcessHandle({ maxRetainedProcessOutputBytes: 1024 * 1024 });\n  } else throw e;\n}","preventionTips":["Coerce and floor config values from env/CLI to safe integers before use.","Use integer math (n * 1024 * 1024) rather than fractional multipliers for byte limits.","Validate with Number.isSafeInteger at config-loading time, not at construction."],"tags":["validation","range-error","process"],"backgroundTag":"invalid-parameter-value","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}