Skip to content

Odoo Stock Move Cancelled — 'Cannot Process Cancelled Move' and Stuck Transfers Fix

DeployMonkey Team · March 24, 2026 9 min read

Cancelled Stock Move Errors

When processing inventory operations, cancelled stock moves block further action:

UserError: You cannot process a cancelled stock move.

UserError: This transfer has been cancelled and cannot be validated.

Warning: Some stock moves in this transfer are in cancelled state.

UserError: Cannot unreserve a cancelled move.

Why Stock Moves Get Cancelled

  • User clicked "Cancel" on a delivery/receipt/transfer
  • The linked sale order or purchase order was cancelled
  • "No Backorder" was chosen on partial delivery (remaining moves cancelled)
  • A procurement was cancelled by the scheduler
  • Manual cancellation of individual moves within a picking

Fix 1: Recreate the Transfer

# If the entire transfer was cancelled:
# You cannot "uncancel" it — create a new one

# From Sale Order:
# Open the SO > Delivery smart button
# If all deliveries are cancelled, the SO may allow a new delivery
# Click "Delivery" or process a new quotation

# From Purchase Order:
# Open the PO > Receipt smart button
# Create a new receipt manually if needed

# Manual transfer:
# Inventory > Operations > Transfers > Create
# Set operation type, products, quantities, and source/destination

Fix 2: Partial Cancellation Recovery

# If some moves in a transfer are cancelled but others are not:

# Check the picking state:
sudo -u postgres psql -d mydb -c "
  SELECT sp.id, sp.name, sp.state,
    sm.id as move_id, sm.product_id, pt.name as product,
    sm.product_uom_qty, sm.state as move_state
  FROM stock_picking sp
  JOIN stock_move sm ON sm.picking_id = sp.id
  JOIN product_product pp ON sm.product_id = pp.id
  JOIN product_template pt ON pp.product_tmpl_id = pt.id
  WHERE sp.id = PICKING_ID;
"

# If some moves are 'cancel' and some are 'assigned':
# The non-cancelled moves can still be processed
# But the picking state may show 'cancel'

# Fix: Reset picking state to match active moves
# This requires careful database intervention or ORM manipulation

Fix 3: Accidental Cancellation Recovery

# If a transfer was cancelled by mistake:

# Option 1: Create a new transfer with same details
# Inventory > Transfers > Create
# Copy the product lines from the cancelled transfer

# Option 2: Reset via database (development only)
sudo -u postgres psql -d mydb -c "
  -- Check if the transfer has any done moves
  SELECT COUNT(*) FROM stock_move
  WHERE picking_id = PICKING_ID AND state = 'done';
"

# If no done moves, you could reset:
sudo -u postgres psql -d mydb -c "
  UPDATE stock_picking SET state = 'draft' WHERE id = PICKING_ID;
  UPDATE stock_move SET state = 'draft' WHERE picking_id = PICKING_ID AND state = 'cancel';
  UPDATE stock_move_line SET state = 'draft' WHERE picking_id = PICKING_ID AND state = 'cancel';
"
# WARNING: Only do this if no quantities were actually processed

Fix 4: Sale Order Delivery After Cancel

# If the SO delivery was cancelled but the SO is still valid:

# Check SO delivery status:
# Sale > Orders > select SO
# Check: Delivery Status field

# If "Nothing to Deliver" but items were not actually shipped:
# The stock moves were cancelled with "No Backorder"

# Fix: Create a manual delivery
# 1. Inventory > Transfers > Create
# 2. Operation Type: Delivery Orders
# 3. Add product lines matching the SO
# 4. Source Location: WH/Stock
# 5. Destination: Partner/Customer
# 6. Set the Source Document to the SO number

Fix 5: Procurement Cancellation Recovery

# MTO/MTS procurements that were cancelled:

# Check procurement groups:
sudo -u postgres psql -d mydb -c "
  SELECT pg.name, sm.origin, sm.state, sm.product_id,
    sm.product_uom_qty
  FROM stock_move sm
  LEFT JOIN procurement_group pg ON sm.group_id = pg.id
  WHERE sm.origin LIKE 'SO%'
  AND sm.state = 'cancel'
  ORDER BY sm.create_date DESC LIMIT 20;
"

# Re-trigger procurement:
# Run the scheduler: Inventory > Operations > Run Scheduler
# Or manually create the needed PO/MO

Fix 6: Prevent Accidental Cancellations

# Restrict cancellation permissions:
# Use record rules or custom access rights
# Only Inventory Managers should be able to cancel transfers

# Add confirmation dialogs:
# Custom module can add a wizard to confirm cancellation
# This prevents one-click accidental cancellation

# Use the Audit Log to track who cancelled what:
# Settings > Technical > Audit Log (if enabled)

Prevention

DeployMonkey's AI agent monitors stock move states and detects accidental cancellations. The agent provides recovery guidance and prevents unauthorized cancellations through proper access control configuration.