moeru-ai/airi · error · Error

Invalid position to break block at.

Error message

Invalid position to break block at.

What it means

Thrown by validatePosition inside breakBlockAt when any of x, y, or z is null or undefined (uses == null loose equality, catching both). This is a programmer/planner error, not a runtime game-state error: the function signature expects numbers, so a null coordinate means the caller passed garbage. Note this is a plain Error, not an ActionError — it does not carry a code.

Source

Thrown at integrations/minecraft/src/skills/blocks.ts:47

  if (isUnbreakableBlock(block))
    return false

  if (mineflayer.allowCheats) {
    return breakWithCheats(mineflayer, x, y, z)
  }

  await moveIntoRange(mineflayer, block)

  if (mineflayer.isCreative) {
    return breakInCreative(mineflayer, block, x, y, z)
  }

  return breakInSurvival(mineflayer, block, x, y, z)
}

function validatePosition(x: number, y: number, z: number) {
  if (x == null || y == null || z == null) {
    throw new Error('Invalid position to break block at.')
  }
}

function isUnbreakableBlock(block: any): boolean {
  return block.name === 'air' || block.name === 'water' || block.name === 'lava'
}

async function breakWithCheats(mineflayer: Mineflayer, x: number, y: number, z: number): Promise<boolean> {
  mineflayer.bot.chat(`/setblock ${Math.floor(x)} ${Math.floor(y)} ${Math.floor(z)} air`)
  log(mineflayer, `Used /setblock to break block at ${x}, ${y}, ${z}.`)
  return true
}

async function moveIntoRange(mineflayer: Mineflayer, block: any) {
  if (mineflayer.bot.entity.position.distanceTo(block.position) > 4.5) {
    const pos = block.position
    const movements = new Movements(mineflayer.bot)
    movements.allowParkour = false

View on GitHub (pinned to 27111382b4)

Solutions

  1. Validate coordinates at the call site before invoking breakBlockAt: if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z)) throw ...
  2. Coerce with defaults: const { x = 0, y = 0, z = 0 } = pos; — only if zero is a sensible fallback.
  3. Inspect the planner output schema to ensure x, y, z are always present and numeric.
  4. Tighten the function signature to a Vec3 or a branded Position type so TypeScript rejects null at compile time.

Example fix

// before
breakBlockAt(mineflayer, pos.x, pos.y, pos.z) // pos.z undefined

// after
if (pos?.x == null || pos?.y == null || pos?.z == null) {
  throw new TypeError('breakBlockAt requires finite x, y, z')
}
await breakBlockAt(mineflayer, pos.x, pos.y, pos.z)
Defensive patterns

Strategy: validation

Validate before calling

function isValidPos(x: unknown, y: unknown, z: unknown): x is number {
  return typeof x === 'number' && Number.isFinite(x)
    && typeof y === 'number' && Number.isFinite(y)
    && typeof z === 'number' && Number.isFinite(z)
}
if (!isValidPos(pos.x, pos.y, pos.z)) {
  throw new TypeError(`Invalid position: ${JSON.stringify(pos)}`)
}

Type guard

type Vec3Like = { x: number; y: number; z: number }
function isVec3(v: unknown): v is Vec3Like {
  return typeof v === 'object' && v !== null
    && typeof (v as any).x === 'number'
    && typeof (v as any).y === 'number'
    && typeof (v as any).z === 'number'
}

Try / catch

if (pos?.x == null || pos?.y == null || pos?.z == null) {
  throw new TypeError('breakBlockAt requires finite x, y, z')
}
try {
  await breakBlockAt(mineflayer, pos.x, pos.y, pos.z)
} catch (e) {
  if (e instanceof Error && e.message === 'Invalid position to break block at.') {
    // coordinate source is buggy; log and skip
  } else throw e
}

Prevention

When it happens

Trigger: Passing undefined to breakBlockAt because the planner destructured a missing field ({x, y} with no z); passing NaN (note: NaN == null is false, so NaN slips through and would fail later at blockAt); JSON config with a null coordinate; optional-chained property access returning undefined.

Common situations: LLM planner emits a coordinate object missing a key; position read from a partial block record; off-by-one in an array index returning undefined; refactored call site that previously accepted a Vec3 but now takes three numbers.

Related errors


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