{"record":{"id":"c4a131253d4160f0","repo":"heygen-com/hyperframes","slug":"engine-config-field-must-be-a-integer-fini","errorCode":null,"errorMessage":"Engine config ${field} must be a ${integer ? \"finite integer\" : \"finite number\"} >= ${min}","messagePattern":"Engine config (.+?) must be a (.+?) >= (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/engine/src/config.ts","lineNumber":390,"sourceCode":"    !Array.isArray(value) &&\n    [Object.prototype, null].includes(Object.getPrototypeOf(value))\n  );\n}\n\nfunction assertEngineConfigNumber(\n  config: Record<string, unknown>,\n  field: string,\n  min: number,\n  integer = false,\n): void {\n  const value = config[field];\n  if (\n    typeof value !== \"number\" ||\n    !Number.isFinite(value) ||\n    value < min ||\n    (integer && !Number.isInteger(value))\n  ) {\n    throw new Error(\n      `Engine config ${field} must be a ${integer ? \"finite integer\" : \"finite number\"} >= ${min}`,\n    );\n  }\n}\n\nfunction assertPositiveEngineConfigNumber(config: Record<string, unknown>, field: string): void {\n  const value = config[field];\n  if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n    throw new Error(`Engine config ${field} must be a finite number > 0`);\n  }\n}\n\nfunction assertEngineConfigEnum(\n  config: Record<string, unknown>,\n  field: string,\n  values: readonly unknown[],\n): void {\n  if (!values.includes(config[field])) throw new Error(`Engine config ${field} is invalid`);","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/engine/src/config.ts#L372-L408","documentation":"assertEngineConfigNumber() validates a numeric engine-config field has a finite value at or above a minimum (and is an integer when the field demands it). It is applied to jpegQuality (>=0), minParallelFrames & largeRenderThreshold (>=0, integer), streamingEncodeMaxDurationSeconds & audioGain (>=0), the POSITIVE_NUMBER fields like timeouts/chunkSizeFrames (>=1), frameDataUriCacheLimit (>=1, integer), and expectedChromiumMajor (>=1, integer when present).","triggerScenarios":"Calling validateEngineConfigSnapshot(value) — i.e. crossing a JSON wire boundary such as a serialized render request — with one of those fields set to a string, NaN/Infinity, a negative number, a float where an integer is required, or below the field's minimum (e.g. `jpegQuality: -5`, `browserTimeout: 0`, `chunkSizeFrames: 1.5`).","commonSituations":"Hand-editing a serialized render config; a stale client sending an old schema; env-var override misparsed to a string; JSON deserialization of a config that was never run through resolveConfig(); passing a partial snapshot that skipped orchestrator defaults.","solutions":["Read the field name and the required minimum in the message, then set that field in the snapshot to a finite number at/above the minimum.","For integer fields (minParallelFrames, largeRenderThreshold, frameDataUriCacheLimit, expectedChromiumMajor) ensure the value has no fractional part.","Prefer building the snapshot via resolveConfig() (which fills defaults) rather than hand-authoring JSON.","Validate the snapshot with validateEngineConfigSnapshot() during development to catch the field before it reaches the wire."],"exampleFix":"// before\nconst snapshot = { ...DEFAULT_CONFIG, browserTimeout: 0, chunkSizeFrames: 1.5 };\nvalidateEngineConfigSnapshot(snapshot); // throws on browserTimeout\n\n// after\nconst snapshot = { ...DEFAULT_CONFIG, browserTimeout: 60_000, chunkSizeFrames: 360 };\nvalidateEngineConfigSnapshot(snapshot);","handlingStrategy":"validation","validationCode":"function assertNumericField(field: string, value: unknown, min: number, integer = false): void {\n  if (typeof value !== \"number\" || !Number.isFinite(value) || value < min) {\n    throw new Error(`${field} must be a finite number >= ${min}`);\n  }\n  if (integer && !Number.isInteger(value)) {\n    throw new Error(`${field} must be an integer >= ${min}`);\n  }\n}\n\n// call before validateEngineConfigSnapshot for clear errors:\nassertNumericField(\"browserTimeout\", cfg.browserTimeout, 1);\nassertNumericField(\"chunkSizeFrames\", cfg.chunkSizeFrames, 1, true);","typeGuard":"function isFiniteNumberAtLeast(value: unknown, min: number, integer = false): boolean {\n  return typeof value === \"number\"\n    && Number.isFinite(value)\n    && value >= min\n    && (!integer || Number.isInteger(value));\n}","tryCatchPattern":"try {\n  validateEngineConfigSnapshot(snapshot);\n} catch (e) {\n  if (/Engine config .* must be a .* number/.test(String(e))) {\n    throw new Error(`Rejecting render request: ${e.message}`, { cause: e });\n  }\n  throw e;\n}","preventionTips":["Build snapshots with resolveConfig(overrides) so defaults and coercion happen first.","Validate the snapshot at the trust boundary (right after JSON deserialization).","Coerce env-var-derived numbers with `Number(...)` and reject NaN before snapshotting."],"tags":["engine-config","validation","snapshot","numeric"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}