Zie619/n8n-workflows · error · Error

Insufficient stock for ${$('Retrieve Issue Request Details')

Error message

Insufficient stock for ${$('Retrieve Issue Request Details').first().json['Product ID']}

What it means

Thrown by the 'Update Stock' Code node during issue-request approval: currentStock minus approvedQuantity would go below zero. This is a deliberate business-rule guard preventing negative inventory in the Google Sheets stock ledger.

Source

Thrown at workflows/Code/0926_Code_Webhook_Create_Webhook.json:258

              "value": "={{ $json.body['Measurement Unit'] }}"
            }
          ]
        },
        "includeOtherFields": "="
      },
      "typeVersion": 3.4,
      "notes": "This set node performs automated tasks as part of the workflow."
    },
    {
      "id": "47d2bb01-99e6-4ab1-b19d-bc9912243150",
      "name": "Update Stock",
      "type": "n8n-nodes-base.code",
      "position": [
        7440,
        3860
      ],
      "parameters": {
        "jsCode": "const currentStock = parseFloat($input.first().json['Current Stock']\n );\nconst approvedQuantity = parseFloat(\n $('Verify Approval Data').first().json['Approved Quantity']);\nconst newStock = currentStock - approvedQuantity;\n\nif (newStock < 0) throw new Error(`Insufficient stock for ${\n  $('Retrieve Issue Request Details').first().json['Product ID']}`);\n\nreturn {\n  json: {\n    ...$json,\n    \"Updated Current Stock\": newStock,\n\"Material Name\":$input.first().json['Material Name'],\"Measurement Unit\":$input.first().json['Measurement Unit'],\n\"Minimum Stock Level\": \n  $input.first().json['Minimum Stock Level'],\n  \"Issue Date\":\n    $('Retrieve Issue Request Details').first().json['Issue Date'],\n\"Product ID\": \n  $('Retrieve Issue Request Details').first().json['Product ID']\n \n  }\n};"
      },
      "typeVersion": 2,
      "notes": "This code node performs automated tasks as part of the workflow."
    },
    {
      "id": "dcbb196f-1ecf-4137-af29-e511c4b7b9d9",
      "name": "Receive Issue Request",
      "type": "n8n-nodes-base.webhook",
      "position": [
        5900,
        3400
      ],
      "webhookId": "73d4bdfc-2d8b-42f4-85d5-43ecae0953c1",
      "parameters": {
        "path": "raw-materials-issue",
        "options": {},
        "httpMethod": "POST"
      },

View on GitHub (pinned to 94007c1445)

Solutions

  1. Verify the stock lookup row matched the correct Product ID and the Current Stock cell is a plain number.
  2. Validate Approved Quantity against available stock BEFORE sending the approval request (the workflow has a 'Verify Requested Quantity' node - enforce it in the approval UI too).
  3. Make the update atomic: re-read stock immediately before writing and use sheet locking or single-writer pattern to avoid race conditions.
  4. Decide the business path for insufficient stock: reject with a message to the approver instead of an unhandled throw.

Example fix

// before
const newStock = currentStock - approvedQuantity;
if (newStock < 0) throw new Error(`Insufficient stock for ${$('Retrieve Issue Request Details').first().json['Product ID']}`);

// after
const currentStock = parseFloat($input.first().json['Current Stock']);
const approvedQuantity = parseFloat($('Verify Approval Data').first().json['Approved Quantity']);
if (!Number.isFinite(currentStock)) throw new Error(`Current Stock is not a number: ${$input.first().json['Current Stock']}`);
if (!Number.isFinite(approvedQuantity)) throw new Error(`Approved Quantity is not a number`);
const newStock = currentStock - approvedQuantity;
if (newStock < 0) throw new Error(`Insufficient stock for ${$('Retrieve Issue Request Details').first().json['Product ID']}: have ${currentStock}, approved ${approvedQuantity}`);
Defensive patterns

Strategy: validation

Validate before calling

const currentStock = parseFloat($input.first().json['Current Stock']);
const approvedQuantity = parseFloat($('Verify Approval Data').first().json['Approved Quantity']);
if (!Number.isFinite(currentStock)) throw new Error(`Current Stock not numeric: ${$input.first().json['Current Stock']}`);
if (!Number.isFinite(approvedQuantity)) throw new Error('Approved Quantity not numeric');
if (currentStock - approvedQuantity < 0) throw new Error(`Insufficient stock: have ${currentStock}, approved ${approvedQuantity}`);

Type guard

const isPositiveNumber = (v) => Number.isFinite(v) && v > 0;

Prevention

When it happens

Trigger: `Current Stock` from the stock lookup row is less than `Approved Quantity` from the approval webhook; `Current Stock` parsed as NaN (parseFloat of empty/absent sheet cell gives NaN, and NaN < 0 is false, but a 0 stock with positive approval triggers it); the sheet row for the Product ID holds stale stock after concurrent approvals.

Common situations: Approver approves more than available stock; two approvals race and the second sees outdated stock; sheet cell formatted as text or with currency symbols so parseFloat yields NaN or wrong values; sheet row lookup returned the wrong row.

Related errors


AI-assisted analysis of Zie619/n8n-workflows@94007c1445 (2026-08-15). Data as JSON: /api/errors/b99315ec9eff4043. Report an issue: GitHub.