moeru-ai/airi · warning · ActionError
RESOURCE_MISSING
RESOURCE_MISSING
Error message
Cannot craft ${itemName} - missing: ${missingList} What it means
Thrown by the recursion-guard branch when planRecipe can partially resolve planks/stick/crafting_table but plan.missing has entries — a precise list of ingredients the bot lacks. This is the most actionable crafting failure: the context.missing map tells you exactly what to gather. RESOURCE_MISSING because the path is known but materials are absent.
Source
Thrown at integrations/minecraft/src/skills/crafting.ts:187
const stepRecipes = mineflayer.bot.recipesFor(stepItemId, null, 1, null)
if (stepRecipes && stepRecipes.length > 0) {
const outputPerCraft = stepRecipes[0].result?.count ?? 1
const craftCount = Math.ceil(step.amount / outputPerCraft)
await mineflayer.bot.craft(stepRecipes[0], craftCount)
logger.log(`Successfully crafted ${craftCount}x ${step.item}`)
}
}
}
return true
}
// Can't craft - provide helpful error message
if (Object.keys(plan.missing).length > 0) {
const missingList = Object.entries(plan.missing)
.map(([item, count]) => `${count}x ${item}`)
.join(', ')
throw new ActionError('RESOURCE_MISSING', `Cannot craft ${itemName} - missing: ${missingList}`, {
item: itemName,
missing: plan.missing,
})
}
throw new ActionError('RESOURCE_MISSING', `Cannot craft ${itemName} - missing ingredients`, { item: itemName })
}
// Step 2: Find and use a crafting table
// This will throw if it fails hard
logger.log(`Step 2: Find and use a crafting table`)
const craftingTableRange = 32
if (await findAndUseCraftingTable(craftingTableRange)) {
return true
}
// If we got here, maybe we didn't have recipes even with a table?
// Let's verify if resources are missingView on GitHub (pinned to 27111382b4)
Solutions
- Read err.context.missing and gather each entry: for 'oak_log' use collectBlock(mineflayer, 'oak_log', count).
- Re-run craftRecipe after gathering; the planner will re-evaluate.
- If a missing item is itself craftable, recurse via craftRecipe on it first.
- Surface the missing list to the planner so it can prioritize harvesting.
Example fix
// before
await craftRecipe(mineflayer, 'oak_planks', 4)
// after
try {
await craftRecipe(mineflayer, 'oak_planks', 4)
} catch (e) {
if (e instanceof ActionError && e.code === 'RESOURCE_MISSING' && e.context?.missing) {
for (const [item, count] of Object.entries(e.context.missing)) {
await collectBlock(mineflayer, item, count as number)
}
await craftRecipe(mineflayer, 'oak_planks', 4)
} else throw e
} Defensive patterns
Strategy: validation
Validate before calling
function missingMaterials(mineflayer: Mineflayer, itemName: string, num: number): Record<string, number> {
const plan = planRecipe(mineflayer.bot, itemName, num)
return plan.status === 'ok' ? plan.missing : {}
} Try / catch
try {
await craftRecipe(mineflayer, itemName, num)
} catch (e) {
if (e instanceof ActionError && e.code === 'RESOURCE_MISSING' && e.context?.missing) {
for (const [item, count] of Object.entries(e.context.missing as Record<string, number>)) {
await collectBlock(mineflayer, item, count)
}
await craftRecipe(mineflayer, itemName, num)
} else throw e
} Prevention
- Gather the full ingredient tree before crafting — use planRecipe to enumerate it.
- Read context.missing to drive harvesting precisely.
- Recurse on missing intermediates that are themselves craftable.
- Keep base materials (logs, cobblestone) stocked in a base chest.
When it happens
Trigger: Trying to craft oak_planks with no logs in inventory (missing: { oak_log: 1 }); crafting a stick without planks; crafting_table without planks; plan can compute the tree but inventory does not satisfy the leaves.
Common situations: Bot tried to craft before gathering logs; logs were deposited to a chest; partial inventory after death; LLM skipped the gather step.
Related errors
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/d1b1b26000baef55.
Report an issue: GitHub.