{"record":{"id":"b918d6671edb7460","repo":"moeru-ai/airi","slug":"the-var-order-must-be-a-positive-integer","errorCode":null,"errorMessage":"The VAR order must be a positive integer.","messagePattern":"The VAR order must be a positive integer\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/motion-driver-magic/src/shared/var.ts","lineNumber":75,"sourceCode":"}\n\nfunction createResiduals(frames: readonly number[][], coefficients: readonly number[][], order: number): number[][] {\n  const channelCount = frames[0].length\n  const residuals: number[][] = []\n  for (let frameIndex = order; frameIndex < frames.length; frameIndex++) {\n    const feature = createAutoregressiveFeature(frames, order, channelCount, frameIndex)\n    const prediction = predictAutoregressiveValues(coefficients, feature)\n    residuals.push(frames[frameIndex].map((value, channel) => value - prediction[channel]))\n  }\n  return residuals\n}\n\n/** Fits the VAR parameters that both public methods use. */\nexport function fitVarParameters(sequence: TrainingSequence, options: VarFitOptions): VarParameters {\n  if (!Number.isFinite(sequence.sampleRateHz) || sequence.sampleRateHz <= 0)\n    throw new Error('The motion sample rate must be positive.')\n  if (options.order < 1 || !Number.isInteger(options.order))\n    throw new Error('The VAR order must be a positive integer.')\n\n  const frames = sequence.frames\n  if (frames.length === 0 || frames[0].length === 0)\n    throw new Error('The motion sequence must contain at least one value.')\n  if (frames.some(frame => frame.length !== frames[0].length))\n    throw new Error('Every motion frame must have the same number of values.')\n\n  const channels = createMotionChannels(frames)\n  if (channels.length === 0)\n    throw new Error('The current motion has no changing channels.')\n  if (frames.length <= options.order + 1)\n    throw new Error('The current motion is too short for this VAR order.')\n\n  const baselineFrame = createBaselineFrame(frames)\n  const trainingFrames = frames.map(frame => channels.map(\n    channel => (frame[channel.valueIndices[0]] - channel.mean) / channel.scale,\n  ))\n  const coefficients = fitCoefficients(trainingFrames, options)","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/moeru-ai/airi/blob/9c213115f8bd0fff9e6eabab02b077ac32da21be/packages/motion-driver-magic/src/shared/var.ts#L57-L93","documentation":"The VAR model uses `options.order` past frames to predict the current frame; an order below 1 or non-integer yields no autoregressive window or malformed lag matrices, so it is rejected at the top of `fitVarParameters`.","triggerScenarios":"Calling `fitVarParameters` or `createArHmmModel` with `order: 0`, negative order, or fractional values (e.g. computed as `dataSeconds * 2` = 2.5). Also when order comes from a slider storing floats.","commonSituations":"Config default of 0 meaning 'auto'; a UI slider emitting floats; dividing total lag seconds by frame time without rounding; copying an example and editing order to '0 to disable' not realizing it is invalid.","solutions":["Pass an integer `order >= 1`.","Round/clamp computed values: `Math.max(1, Math.round(rawOrder))`.","Validate options with a schema (integer, minimum 1) before fitting.","Keep order well below the frame count — remember rows are reduced by `order` during fitting."],"exampleFix":"// before\nfitVarParameters(seq, { order: 0, ridge: 1e-6 })\n// after\nfitVarParameters(seq, { order: Math.max(1, Math.round(rawOrder)), ridge: 1e-6 })","handlingStrategy":"validation","validationCode":"function isValidOrder(n: unknown): n is number {\n  return typeof n === 'number' && Number.isInteger(n) && n >= 1\n}","typeGuard":null,"tryCatchPattern":"try {\n  fitVarParameters(seq, options)\n} catch (error) {\n  if (error instanceof Error && error.message.includes('VAR order')) {\n    return fitVarParameters(seq, { ...options, order: 2 })\n  }\n  throw error\n}","preventionTips":["Round slider/computed order values before passing them in.","Validate options with a schema (integer >= 1) before fitting.","Keep order well below frame count since fitting loses `order` rows.","Document that 0 is invalid; use order: 1 as the minimal setting."],"tags":["validation","options","var","motion"],"backgroundTag":"invalid-model-options","analyzedSha":"9c213115f8bd0fff9e6eabab02b077ac32da21be","analyzedAt":"2026-09-02T04:27:24.639Z","contentChangedAt":"2026-09-02T04:27:24.639Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}