The Problem
Delivery orders, manufacturing orders, or internal transfers stuck in 'Waiting Another Operation' or 'Ready' state but cannot be processed. Products appear reserved but the operation won't complete.
Cause 1: Waiting for Upstream Operation
# Multi-step routes: Pick → Pack → Ship
# Ship is 'Waiting' because Pack hasn't been validated yet
# Diagnosis:
# Open the stuck move → check 'Move Origin' or source document
# Find the upstream operation and process it first
# Fix: Process operations in order:
# 1. Validate Pick
# 2. Validate Pack
# 3. Then Ship becomes 'Ready'Cause 2: No Stock Available
# Move is 'Waiting Availability' because product is out of stock
# Check stock:
SELECT pp.default_code, sq.quantity, sq.reserved_quantity, sl.complete_name
FROM stock_quant sq
JOIN product_product pp ON sq.product_id = pp.id
JOIN stock_location sl ON sq.location_id = sl.id
WHERE pp.id = PRODUCT_ID AND sl.usage = 'internal';
# Fix options:
# 1. Receive the product (create a receipt)
# 2. Do an inventory adjustment to add stock
# 3. Force availability (if you know stock is physically there)Cause 3: Phantom Reservation (Ghost Quants)
# Stock is reserved by a cancelled/deleted move but not released
# Find over-reserved quants:
SELECT pp.default_code, sq.quantity, sq.reserved_quantity,
sq.reserved_quantity - sq.quantity as over_reserved
FROM stock_quant sq
JOIN product_product pp ON sq.product_id = pp.id
WHERE sq.reserved_quantity > sq.quantity;
# Find what is reserving the stock:
SELECT sm.id, sm.reference, sm.state, sm.product_qty, sm.reserved_qty
FROM stock_move sm
WHERE sm.product_id = PRODUCT_ID
AND sm.state NOT IN ('done', 'cancel')
AND sm.reserved_qty > 0;
# Fix: unreserve the phantom moves
# In Odoo: open the stuck picking → click 'Unreserve'
# Then: click 'Check Availability' on the correct pickingCause 4: Procurement Rule Misconfiguration
# Route says 'Buy' but no vendor is set
# Or route says 'Manufacture' but no BoM exists
# The procurement creates a move but can't fulfill it
# Check the product's routes:
# Product → Inventory tab → Routes
# Verify the route matches reality:
# - Buy: vendor and vendor pricelist set
# - Manufacture: BoM exists
# - Make to Order: upstream supply existsCause 5: Negative Quant
# Negative quants break availability checking
# Find negative quants:
SELECT pp.default_code, sq.quantity, sl.complete_name
FROM stock_quant sq
JOIN product_product pp ON sq.product_id = pp.id
JOIN stock_location sl ON sq.location_id = sl.id
WHERE sq.quantity < 0;
# Fix: do an inventory adjustment to correct the quantity
# Or investigate why it went negative (double processing?)Force Availability (Emergency)
# WARNING: Only use if you know stock is physically present
# but Odoo's reservation system is broken
# In Odoo UI:
# Open the stuck picking
# If button exists: click 'Force Availability' (may need developer mode)
# In Odoo Shell:
picking = env['stock.picking'].browse(PICKING_ID)
for move in picking.move_ids:
move._force_assign()
env.cr.commit()
# Then validate the picking normallyDiagnosis SQL Queries
# All stuck moves for a product:
SELECT sm.id, sm.reference, sm.state, sm.product_qty,
sm.reserved_qty, sp.name as picking
FROM stock_move sm
LEFT JOIN stock_picking sp ON sm.picking_id = sp.id
WHERE sm.product_id = PRODUCT_ID
AND sm.state NOT IN ('done', 'cancel')
ORDER BY sm.date;
# All reservations:
SELECT sml.id, sm.reference, sml.quantity, sml.qty_done,
sl_src.complete_name as source, sl_dst.complete_name as dest
FROM stock_move_line sml
JOIN stock_move sm ON sml.move_id = sm.id
JOIN stock_location sl_src ON sml.location_id = sl_src.id
JOIN stock_location sl_dst ON sml.location_dest_id = sl_dst.id
WHERE sm.product_id = PRODUCT_ID
AND sml.state NOT IN ('done', 'cancel');Prevention
- Process operations in the correct order (pick before pack before ship)
- Run 'Check Availability' regularly on waiting operations
- Keep inventory accurate with regular cycle counts
- Don't manually delete stock moves — cancel them properly
- Monitor negative quants and fix immediately
DeployMonkey
DeployMonkey's AI agent detects stuck stock moves and diagnoses the root cause — upstream operation not processed, phantom reservation, negative quant, or procurement misconfiguration. Fixes suggested automatically.