moeru-ai/airi · warning · Error

Expectation failed: Expected movedDistance >= ${threshold},

Error message

Expectation failed: Expected movedDistance >= ${threshold}, got ${movedDistance}

What it means

globalThis.expectMoved(minBlocks, message) asserts that the most recent movement-bearing action actually displaced the bot by at least `threshold` blocks (default 0.5). It reads globalThis.lastAction.result.movedDistance. A whitelist of non-moving actions (chat, skip, craftRecipe, mineBlockAt, etc.) short-circuits to true because they are not expected to move the bot. For movement actions, if movedDistance is missing or below the threshold, it throws with the actual and expected values.

Source

Thrown at integrations/minecraft/src/cognitive/conscious/js-planner.ts:1252

  const actionName = globalThis.lastAction?.action?.tool
  const nonMovingActions = [
    'chat', 'giveUp', 'skip', 'stop', 'followPlayer', 'clearFollowTarget',
    'givePlayer', 'consume', 'equip', 'putInChest', 'takeFromChest', 'discard',
    'collectBlocks', 'mineBlockAt', 'craftRecipe', 'smeltItem', 'clearFurnace',
    'placeHere', 'attack', 'attackPlayer', 'activate', 'recipePlan',
  ]

  if (!globalThis.lastAction || (typeof actionName === 'string' && nonMovingActions.includes(actionName)))
    return true

  const movedDistance = typeof globalThis.lastAction?.result?.movedDistance === 'number'
    ? globalThis.lastAction.result.movedDistance
    : 0

  if (movedDistance >= threshold)
    return true

  throw new Error(
    'Expectation failed: ' + __plannerExpectationDetail(message, 'Expected movedDistance >= ' + threshold + ', got ' + movedDistance),
  )
}

globalThis.expectNear = (targetOrMaxDist, maxDistOrMessage, maybeMessage) => {
  let target = null
  let maxDist = 2
  let message

  if (targetOrMaxDist && typeof targetOrMaxDist === 'object' && typeof targetOrMaxDist.x === 'number' && typeof targetOrMaxDist.y === 'number' && typeof targetOrMaxDist.z === 'number') {
    target = { x: targetOrMaxDist.x, y: targetOrMaxDist.y, z: targetOrMaxDist.z }
    if (typeof maxDistOrMessage === 'number')
      maxDist = maxDistOrMessage
    if (typeof maybeMessage === 'string')
      message = maybeMessage
  }
  else {
    if (typeof targetOrMaxDist === 'number')

View on GitHub (pinned to 27111382b4)

Solutions

  1. Check globalThis.lastAction.result.movedDistance via log() before asserting, to see the actual displacement.
  2. Lower the threshold or omit it to use the 0.5 default if the move was intentionally short.
  3. Confirm the preceding action is actually a movement action and not misclassified.
  4. If a movement action was renamed, add the new name to the nonMovingActions list in the planner bootstrap, or ensure movement actions report movedDistance.

Example fix

// before
//   await use('moveTo', { x: 10, y: 64, z: -5 })
//   expectMoved(2)  // throws if bot only nudged 0.3 blocks
//
// after
//   const r = await use('moveTo', { x: 10, y: 64, z: -5 })
//   log('moved', r.result.movedDistance)
//   expectMoved(0.5, `reached target, moved ${r.result?.movedDistance}`)
Defensive patterns

Strategy: validation

Validate before calling

// Before expectMoved, confirm the last action reports telemetry:
// const r = globalThis.lastAction?.result
// if (typeof r?.movedDistance === 'number') {
//   expectMoved(threshold, `displaced ${r.movedDistance}`)
// } else {
//   log('expectMoved skipped: no movedDistance on last action')
// }

Type guard

function hasMovedDistance(r: unknown): r is { movedDistance: number } {
  return !!r && typeof r === 'object' && typeof (r as any).movedDistance === 'number'
}

Prevention

When it happens

Trigger: Calling expectMoved() after a moveTo/navigate action that pathfinder could not complete (movedDistance 0 or <0.5); the action result object omitted a numeric movedDistance field; the bot was already at the goal so net displacement was under threshold; a movement action was blocked by terrain and the result still came back ok:true with low displacement.

Common situations: Goal coordinates equal the bot's current position; pathfinder stuck against a wall or in a liquid; action result schema changed and no longer reports movedDistance; threshold set too high for short hops; calling expectMoved right after a whitelisted action whose name was recently renamed so it is no longer in nonMovingActions.

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/cbc67b39485dc2ea. Report an issue: GitHub.