A JSON stock record is keyed by SKU. A lookup for constructor appears to find something even though the payload contains no such SKU. The in operator includes inherited properties, so it can answer a different question from “did this stock record contain the requested key?”

For a Shopify 3PL review tool, check the record's own property before interpreting the quantity. Object.hasOwn() excludes inherited properties. It also avoids calling a method through a record that might itself contain a key named hasOwnProperty.

Separate a missing key from an available quantity of zero

This local helper is for objects obtained from parsed JSON stock data. It reads one requested field, validates its quantity and returns a distinct missing result. It does not normalize SKU spelling, mutate stock or submit an order.

'use strict'; const assert = require('node:assert/strict'); function readStock(record, sku) { if (record === null || typeof record !== 'object' || Array.isArray(record)) throw new Error('Stock record required'); if (typeof sku !== 'string' || sku.length === 0) { throw new Error('Nonempty SKU text required'); } if (!Object.hasOwn(record, sku)) return { found: false }; const quantity = record[sku]; if (!Number.isSafeInteger(quantity) || quantity < 0) { throw new Error('Nonnegative safe integer quantity required'); } return { found: true, quantity }; } const stock = JSON.parse( '{"toString":0,"__proto__":4,"hasOwnProperty":3,"SKU-7":2}'); const before = JSON.stringify(stock); assert.deepEqual(readStock(stock, 'toString'), { found: true, quantity: 0 }); assert.deepEqual(readStock(stock, '__proto__'), { found: true, quantity: 4 }); assert.deepEqual(readStock(stock, 'hasOwnProperty'), { found: true, quantity: 3 }); assert.deepEqual(readStock(stock, 'SKU-7'), { found: true, quantity: 2 }); assert.deepEqual(readStock(stock, 'constructor'), { found: false }); assert.deepEqual(readStock(stock, 'sku-7'), { found: false }); assert.deepEqual(readStock(Object.create({ X: 99 }), 'X'), { found: false }); for (const json of ['{"X":-1}', '{"X":1.5}', '{"X":"2"}', '{"X":null}', '{"X":true}', '{"X":1e309}', '{"X":9007199254740992}']) { assert.throws(() => readStock(JSON.parse(json), 'X')); } for (const value of [null, [], 'stock']) { assert.throws(() => readStock(value, 'X')); } assert.throws(() => readStock(stock, '')); assert.equal(JSON.stringify(stock), before); console.log('Own-key stock lookup checks passed'); 

Save as own-stock-key.cjs and run node own-stock-key.cjs with Node.js 24. The checks exercise inherited names, an own zero value, keys resembling object methods, case-sensitive identity, invalid quantities and preservation of the input record. The __proto__ field in this example comes from JSON.parse(); this is a read operation, not an example of assigning keys into another object.

Keep the boundary explicit

A drop shipping feed and a shopify fulfillment review may use different record shapes. Apply this helper only after confirming that the input is the expected JSON object keyed by SKU. It is not a validator for arbitrary live objects, proxies, getters or an entire warehouse response.

In a China fulfillment view, a missing key needs an explicit next decision; it should not become a positive balance or silently become zero. A China 3PL adapter must separately establish what the reported quantity means before using it to release work.

If a hypothetical integration brief is named “International Fulfillment for Folligen,” the actual schema and SKU contract still need confirmation. I work with YX Fulfillment; its Shopify handover guide provides related operational context. This executable lookup example makes no claim of a deployed connector or a tested store integration.

Workstations with monitors and printers in a warehouse handling area

Warehouse workstations and equipment.