moeru-ai/airi · error · Error

The current motion is too short for this AR-HMM shape.

Error message

The current motion is too short for this AR-HMM shape.

What it means

After fitting VAR parameters, the library checks that the number of training rows (frames minus VAR order) is at least `stateCount * (featureCount + 1)`. Below that threshold, each hidden state cannot be assigned enough data for stable per-state parameter estimation, so fitting is refused rather than producing a degenerate/overfit model.

Source

Thrown at packages/motion-driver-magic/src/ar-hmm.ts:368

    }
  }
  return { gamma, transitionCounts, logLikelihood }
}

/** Creates a linear Gaussian AR-HMM model with deterministic clustering and EM updates. */
export function createArHmmModel(sequence: TrainingSequence, options: FitOptions): ArHmmModel {
  if (options.stateCount < 2 || !Number.isInteger(options.stateCount))
    throw new Error('The AR-HMM state count must be an integer greater than one.')
  if (options.iterations < 1 || !Number.isInteger(options.iterations))
    throw new Error('The AR-HMM iteration count must be a positive integer.')

  const sourceModel = fitVarParameters(sequence, {
    order: options.order,
    ridge: options.ridge,
  })
  const rowCount = sourceModel.trainingFrames.length - options.order
  if (rowCount < options.stateCount * (sourceModel.featureCount + 1))
    throw new Error('The current motion is too short for this AR-HMM shape.')

  const clusterFeatures = createClusterFeatures(sourceModel.trainingFrames, options.order)
  const assignments = initializeAssignments(clusterFeatures, options.stateCount)
  let expectation = createInitialExpectations(assignments, options.stateCount)
  let stateParameters = maximizeParameters(sourceModel, expectation, options)
  const logLikelihoods: number[] = []
  for (let iteration = 0; iteration < options.iterations; iteration++) {
    expectation = expectationStep(sourceModel, stateParameters, options)
    logLikelihoods.push(expectation.logLikelihood)
    stateParameters = maximizeParameters(sourceModel, expectation, options)
  }
  expectation = expectationStep(sourceModel, stateParameters, options)
  logLikelihoods.push(expectation.logLikelihood)

  const stateWeights = Array.from({ length: options.stateCount }, (_, state) => expectation.gamma.reduce(
    (sum, probabilities) => sum + probabilities[state],
    0,
  ))

View on GitHub (pinned to 9c213115f8)

Solutions

  1. Record a longer motion clip so `frames.length - order >= stateCount * (featureCount + 1)`.
  2. Reduce `stateCount` in FitOptions to fit the available data.
  3. Reduce the VAR `order` to recover rows lost to the autoregressive lag.
  4. Lower the input feature dimensionality (fewer pose channels) before fitting.
  5. Compute the required minimum length beforehand and warn users their capture is too short.

Example fix

// before
createArHmmModel(shortClip, { stateCount: 12, order: 4 })
// after
const minFrames = 12 * (featureCount + 1) + 4
if (shortClip.frames.length < minFrames)
  throw new Error(`Need at least ${minFrames} frames`)
createArHmmModel(shortClip, { stateCount: 4, order: 2 })
Defensive patterns

Strategy: validation

Validate before calling

function hasEnoughFrames(seq: TrainingSequence, stateCount: number, order: number): boolean {
  const featureCount = seq.frames[0]?.length ?? 0
  const rowCount = seq.frames.length - order
  return rowCount >= stateCount * (featureCount + 1)
}

Try / catch

try {
  const model = createArHmmModel(seq, options)
} catch (error) {
  if (error instanceof Error && error.message.includes('too short')) {
    return createArHmmModel(seq, { ...options, stateCount: 2 })
  }
  throw error
}

Prevention

When it happens

Trigger: Calling `createArHmmModel` with a short recording relative to `stateCount`, `order`, and feature dimensionality — e.g. a 2-second clip at 30Hz (60 frames) with stateCount 10 and many features. Triggered whenever `frames.length - order < stateCount * (featureCount + 1)`.

Common situations: Recording only a few seconds of motion but requesting many states; increasing VAR `order` shrinks usable rows; a high-dimensional pose (many Live2D axes) inflating featureCount; users raising stateCount for richer expressions without lengthening capture.

Related errors


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