{"record":{"id":"d6d4134996f0e3af","repo":"moeru-ai/airi","slug":"resource-missing-d6d413","errorCode":"RESOURCE_MISSING","errorMessage":"Don't have right tools to break ${block.name}","messagePattern":"Don't have right tools to break (.+?)","errorType":"exception","errorClass":"ActionError","httpStatus":null,"severity":"warning","filePath":"integrations/minecraft/src/skills/actions/world-interactions.ts","lineNumber":267,"sourceCode":"\n    // Log game mode\n    logger.log(`Game mode: ${mineflayer.bot.game.gameMode}`)\n\n    if (distance > 4.5) {\n      logger.log(`Moving to block position ${targetPos}`)\n      await goToPosition(mineflayer, targetPos.x, targetPos.y, targetPos.z)\n    }\n\n    if (mineflayer.bot.game.gameMode !== 'creative') {\n      logger.log(`Equipping tool for block: ${block.name}`)\n      await mineflayer.bot.tool.equipForBlock(block)\n      const heldItem = mineflayer.bot.heldItem\n      logger.log(`Held item: ${heldItem?.name || 'none'}`)\n      const itemId = heldItem ? heldItem.type : null\n      logger.log(`Can harvest block: ${block.canHarvest(itemId)}`)\n      if (!block.canHarvest(itemId)) {\n        logger.log(`Don't have right tools to break ${block.name}.`)\n        throw new ActionError('RESOURCE_MISSING', `Don't have right tools to break ${block.name}`, { blockType: block.name })\n      }\n    }\n\n    logger.log(`Can dig block: ${mineflayer.bot.canDigBlock(block)}`)\n    if (!mineflayer.bot.canDigBlock(block)) {\n      logger.log(`Cannot break ${block.name} at ${targetPos}.`)\n      throw new ActionError('UNKNOWN', `Cannot break ${block.name} at ${targetPos}`, { blockType: block.name, position: targetPos })\n    }\n\n    logger.log(`Looking at block ${block.position}`)\n    await mineflayer.bot.lookAt(block.position, true) // Ensure the bot has finished turning\n    await sleep(500)\n\n    try {\n      logger.log(`Starting to dig block ${block.name} at ${block.position}`)\n      // Increase digging time to ensure block is fully broken\n      await mineflayer.bot.dig(block, true)\n      await sleep(1000) // Wait for block to break","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/moeru-ai/airi/blob/27111382b4a79a7e983289d6e983a06af185ed0f/integrations/minecraft/src/skills/actions/world-interactions.ts#L249-L285","documentation":"Thrown by breakBlockAt (world-interactions.ts:267) with code RESOURCE_MISSING when, in non-creative mode, after equipping a tool via bot.tool.equipForBlock(block) the held item cannot harvest the block (block.canHarvest(itemId) returns false). This means the correct tool tier is missing — e.g. diamond needed for obsidian, iron for diamond ore. Context payload is { blockType: block.name }.","triggerScenarios":"Call breakBlockAt on a block that requires a higher tool tier than the bot has: obsidian needs diamond pickaxe, diamond ore needs iron pickaxe, iron ore needs stone pickaxe. The tool is equipped first, but if no suitable tool exists the canHarvest check fails.","commonSituations":"Bot only carries a wooden/stone pickaxe, the required tool is in a chest not inventory, the bot just started and only has a starter pickaxe, or the player低估 the tier needed for the block.","solutions":["Equip a higher-tier pickaxe before calling (e.g. craft/carry iron or diamond).","Use creative mode if tooling is unavailable (gameMode === 'creative' bypasses the check).","Pre-check block.harvests in minecraft-data for the required tool tier and stock accordingly.","Catch RESOURCE_MISSING and trigger a 'gear up' fallback (craft, trade, or takeFromChest the right tool)."],"exampleFix":"// before\nawait breakBlockAt(bot, x, y, z) // on diamond ore with wooden pickaxe\n\n// after\nawait takeFromChest(bot, 'iron_pickaxe', 1)\nawait equip(bot, 'iron_pickaxe')\nawait breakBlockAt(bot, x, y, z)","handlingStrategy":"validation","validationCode":"if (mineflayer.bot.game.gameMode !== 'creative') {\n  const toolNames = mineflayer.bot.inventory.items().map(i => i.name)\n  const hasBetter = ['iron_pickaxe','diamond_pickaxe'].some(n => toolNames.includes(n))\n  if (!hasBetter) await takeFromChest(mineflayer, 'iron_pickaxe', 1)\n}\nawait breakBlockAt(mineflayer, x, y, z)","typeGuard":"const hasToolTier = (bot: Mineflayer, tiers: string[]): boolean =>\n  bot.bot.inventory.items().some(i => tiers.includes(i.name))","tryCatchPattern":"try {\n  await breakBlockAt(mineflayer, x, y, z)\n} catch (e) {\n  if (e instanceof ActionError && e.code === 'RESOURCE_MISSING') {\n    await takeFromChest(mineflayer, 'iron_pickaxe', 1)\n    await breakBlockAt(mineflayer, x, y, z)\n  } else throw e\n}","preventionTips":["Always carry at least an iron pickaxe in survival mining operations.","Look up block.harvestTools in minecraft-data to know the required tier.","Use creative mode when tooling is unavailable (bypasses the canHarvest check)."],"tags":["minecraft","resource-missing","tools","survival","mineflayer"],"backgroundTag":null,"analyzedSha":"27111382b4a79a7e983289d6e983a06af185ed0f","analyzedAt":"2026-08-12T18:33:34.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}