moeru-ai/airi · warning · ActionError

ITEM_NOT_FOUND

ITEM_NOT_FOUND

Error message

You do not have any ${itemName} to equip

What it means

Thrown by equip() when no inventory item's name includes the supplied itemName substring. The lookup uses Array.find with item.name.includes(itemName), so any substring match would have satisfied it; reaching the throw means zero items in inventory contain that substring.

Source

Thrown at integrations/minecraft/src/skills/actions/inventory.ts:24

import { useLogger } from '../../utils/logger'
import { goToPlayer, goToPosition } from '../movement'
import { getNearestBlock } from '../world'

const logger = useLogger()

/**
 * Equip an item from the bot's inventory.
 * @param mineflayer The mineflayer instance.
 * @param itemName The name of the item to equip.
 * @throws {ActionError} When the item is not in inventory.
 */
export async function equip(mineflayer: Mineflayer, itemName: string): Promise<void> {
  const item = mineflayer.bot.inventory
    .items()
    .find(item => item.name.includes(itemName))
  if (!item) {
    logger.log(`You do not have any ${itemName} to equip.`)
    throw new ActionError('ITEM_NOT_FOUND', `You do not have any ${itemName} to equip`, { item: itemName })
  }
  let destination: 'hand' | 'head' | 'torso' | 'legs' | 'feet' = 'hand'
  if (itemName.includes('leggings'))
    destination = 'legs'
  else if (itemName.includes('boots'))
    destination = 'feet'
  else if (itemName.includes('helmet'))
    destination = 'head'
  else if (itemName.includes('chestplate'))
    destination = 'torso'

  await mineflayer.bot.equip(item, destination)
  logger.log(`Equipped ${itemName}.`)
}

/**
 * Discard an item from the bot's inventory.
 * @param mineflayer The mineflayer instance.

View on GitHub (pinned to 27111382b4)

Solutions

  1. Pre-check with getItemCount(mineflayer, itemName) > 0 before calling equip.
  2. Run the appropriate ensure* helper (ensurePickaxe, ensureSword, etc.) before equip.
  3. Add a short sleep (e.g. 200ms) between a craft and equip to allow the inventory slot event to propagate.
  4. Use exact item names from mineflayer.bot.registry.itemsByName to avoid substring mismatches.

Example fix

// before
export async function equip(mineflayer: Mineflayer, itemName: string): Promise<void> {
  const item = mineflayer.bot.inventory.items().find(item => item.name.includes(itemName))
  if (!item) {
    throw new ActionError('ITEM_NOT_FOUND', `You do not have any ${itemName} to equip`, { item: itemName })
  }
  // ...
}

// after — list candidate names so the caller can correct the input
if (!item) {
  const names = mineflayer.bot.inventory.items().map(i => i.name)
  throw new ActionError('ITEM_NOT_FOUND', `You do not have any ${itemName} to equip`, {
    item: itemName,
    inventory: names,
  })
}
Defensive patterns

Strategy: validation

Validate before calling

import { getItemCount } from './inventory'

function hasItem(mineflayer: Mineflayer, itemName: string): boolean {
  return getItemCount(mineflayer, itemName) > 0
}

// Pre-check before equipping
if (!hasItem(mineflayer, itemName)) {
  await ensurePickaxe(mineflayer) // or whichever ensure helper fits
}
await equip(mineflayer, itemName)

Type guard

function findInventoryItem(mineflayer: Mineflayer, itemName: string) {
  return mineflayer.bot.inventory.items().find(i => i.name.includes(itemName))
}

// Use as a guard before equip
const item = findInventoryItem(mineflayer, 'sword')
if (item) {
  await equip(mineflayer, 'sword')
}

Try / catch

import { ActionError } from '../../utils/errors'

try {
  await equip(mineflayer, itemName)
} catch (err) {
  if (err instanceof ActionError && err.code === 'ITEM_NOT_FOUND') {
    // Try to ensure the item via the appropriate helper, then equip once
    if (itemName.includes('pickaxe')) await ensurePickaxe(mineflayer)
    else if (itemName.includes('sword')) await ensureSword(mineflayer)
    else if (itemName.includes('axe')) await ensureAxe(mineflayer)
    await equip(mineflayer, itemName)
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: Calling equip(mineflayer, 'sword') when the bot has no sword in inventory. Calling equip with a misspelled or partial name that does not appear in any item.name. Inventory desync where the server has not yet sent the slot update after a craft/pickup.

Common situations: Caller assumed a tool existed without first running ensure* helpers. itemName typo (e.g. 'pick axe' instead of 'pickaxe'). Item is in the chest or on the ground but not in inventory. Race condition: equip called immediately after craft before the slot event propagated.

Related errors


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