moeru-ai/airi · error · Error

The current motion has no changing channels.

Error message

The current motion has no changing channels.

What it means

After validating frame shape, fitVarParameters derives channels via createMotionChannels, which keeps only value streams that actually change across frames. If no channel varies, the VAR model would divide by zero scale and fit meaningless coefficients, so the function throws. A completely static motion cannot be modeled.

Source

Thrown at packages/motion-driver-magic/src/shared/var.ts:85

  return residuals
}

/** Fits the VAR parameters that both public methods use. */
export function fitVarParameters(sequence: TrainingSequence, options: VarFitOptions): VarParameters {
  if (!Number.isFinite(sequence.sampleRateHz) || sequence.sampleRateHz <= 0)
    throw new Error('The motion sample rate must be positive.')
  if (options.order < 1 || !Number.isInteger(options.order))
    throw new Error('The VAR order must be a positive integer.')

  const frames = sequence.frames
  if (frames.length === 0 || frames[0].length === 0)
    throw new Error('The motion sequence must contain at least one value.')
  if (frames.some(frame => frame.length !== frames[0].length))
    throw new Error('Every motion frame must have the same number of values.')

  const channels = createMotionChannels(frames)
  if (channels.length === 0)
    throw new Error('The current motion has no changing channels.')
  if (frames.length <= options.order + 1)
    throw new Error('The current motion is too short for this VAR order.')

  const baselineFrame = createBaselineFrame(frames)
  const trainingFrames = frames.map(frame => channels.map(
    channel => (frame[channel.valueIndices[0]] - channel.mean) / channel.scale,
  ))
  const coefficients = fitCoefficients(trainingFrames, options)
  const residuals = createResiduals(trainingFrames, coefficients, options.order)
  const squaredResidualSum = residuals.reduce(
    (sum, residual) => sum + residual.reduce((channelSum, value) => channelSum + value ** 2, 0),
    0,
  )

  return {
    options,
    sampleRateHz: sequence.sampleRateHz,
    sourceFrameCount: frames.length,

View on GitHub (pinned to 9c213115f8)

Solutions

  1. Supply a motion sequence that actually animates (values differ across frames)
  2. Check preprocessing/normalization steps that could flatten all values to a constant
  3. Avoid single-frame or repeated-frame inputs; include enough varied frames
  4. Detect constant channels upstream and warn the user instead of reaching the fit call

Example fix

// before
const frames = [[0, 0], [0, 0], [0, 0]] // static motion
fitVarParameters({ frames, ... }, options)
// after
const frames = [[0, 0], [0.5, 1], [1, 0.2]] // values change over time
fitVarParameters({ frames, ... }, options)
Defensive patterns

Strategy: validation

Validate before calling

function hasChangingChannels(frames: number[][]): boolean {
  return frames[0].some((_, i) => frames.some(f => f[i] !== frames[0][i]))
}
if (!hasChangingChannels(sequence.frames)) throw new Error('Motion has no changing channels')

Type guard

function isNonStaticSequence(v: unknown): v is number[][] {
  if (!Array.isArray(v) || v.length < 2 || !Array.isArray(v[0])) return false
  return v[0].some((_, i) => v.some(f => f[i] !== v[0][i]))
}

Try / catch

try {
  const params = fitVarParameters(sequence, options)
} catch (e) {
  if (e instanceof Error && e.message === 'The current motion has no changing channels.') {
    // fall back to a non-parametric idle animation or prompt for another clip
  } else throw e
}

Prevention

When it happens

Trigger: Calling fitVarParameters with a sequence where every frame has identical values (all channels constant), e.g. a single pose repeated N times.

Common situations: Passing a frozen/rest-pose clip as training data; a preprocessing step over-normalized all values to the same constant; slicing a sequence down to one frame (single frame means every channel is constant).

Related errors


AI-assisted analysis of moeru-ai/airi@9c213115f8 (2026-09-02). Data as JSON: /api/errors/09890101839f1c51. Report an issue: GitHub.