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 = falseView on GitHub (pinned to 27111382b4)
Solutions
- Validate coordinates at the call site before invoking breakBlockAt: if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z)) throw ...
- Coerce with defaults: const { x = 0, y = 0, z = 0 } = pos; — only if zero is a sensible fallback.
- Inspect the planner output schema to ensure x, y, z are always present and numeric.
- 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
- Type the planner's coordinate output strictly (Vec3, not partial).
- Reject NaN explicitly — validatePosition's == null check lets NaN through.
- Validate coordinates at the system boundary (LLM output parsing) before passing downstream.
- Use a branded Position type so accidental undefined cannot propagate.
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.