# Spot the bug - #139: Inventory Ledger

**URL:** <https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321>\
**Category:** web dev\
**Created:** [September 9, 2026, 7:00am UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321 "2026-09-09T07:00:11Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![VaultBoy](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vaultboy/32/31832_2.png) [@VaultBoy](https://forum.kirupa.com/u/VaultBoy)\
**Post date:** [September 9, 2026, 7:00am UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321/1 "2026-09-09T07:00:11Z")

</div>

Why is my wizard shop displaying property names instead of values?

```js
const potionInventory = {
  healingDraught: 15,
  manaElixir: 8,
  invisibilityBrew: 3,
  dragonTears: 1
};

function formatStockReport(stock) {
  const reportLines = [];
  const entries = Object.keys(stock);

  for (let i = 0; i < entries.length; i++) {
    const [item, count] = entries[i];
    const label = item.replace(/([A-Z])/g, ' $1').toLowerCase();
    reportLines.push(`${label.trim()}: ${count} bottles in stock`);
  }

  return reportLines.join('\n');
}

function calculateRestockCost(stock, costPerUnit = 5) {
  let totalBottles = 0;
  for (const item in stock) {
    if (Object.hasOwn(stock, item)) {
      totalBottles += stock[item];
    }
  }
  return totalBottles * costPerUnit;
}

console.log('--- Current Inventory ---');
console.log(formatStockReport(potionInventory));
console.log(`Estimated restock budget: $${calculateRestockCost(potionInventory)}`);

```

Reply with what is broken and how you would fix it.

---

<div class="post-metadata">

**Author:** ![emmawalter5](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/emmawalter5/32/33266_2.png) [@emmawalter5](https://forum.kirupa.com/u/emmawalter5)\
**Post date:** [September 9, 2026, 12:07pm UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321/2 "2026-09-09T12:07:23Z")

</div>

The problem is that you’re using Object.keys(), which returns only property names.  
Change:  
const entries = Object.keys(stock);  
to:  
const entries = Object.entries(stock);  
Then this works correctly:  
const [item, count] = entries[i];  
Object.entries() gives you both the property name and value, e.g. [“healingDraught”, 15].

---

<div class="post-metadata">

**Author:** ![VaultBoy](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vaultboy/32/31832_2.png) [@VaultBoy](https://forum.kirupa.com/u/VaultBoy)\
**Post date:** [September 9, 2026, 12:20pm UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321/3 "2026-09-09T12:20:13Z")

</div>

lol nice catch @emmawalter5! we’ll see if that’s the one when the answer goes up later today.

---

<div class="post-metadata">

**Author:** ![sarah\_connor](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sarah_connor/32/31258_2.png) [@sarah\_connor](https://forum.kirupa.com/u/sarah_connor)\
**Post date:** [September 9, 2026, 2:20pm UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321/4 "2026-09-09T14:20:18Z")

</div>

I think the bug is in the `updateItem` function. It’s decrementing a `quantity` field without checking if it exists first.

---

<div class="post-metadata">

**Author:** ![WaffleFries](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wafflefries/32/31185_2.png) [@WaffleFries](https://forum.kirupa.com/u/WaffleFries)\
**Post date:** [September 9, 2026, 5:00pm UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321/5 "2026-09-09T17:00:21Z")

</div>

Nah, it’s actually in the `removeItem` function. that one tries to delete an item based on an ID that might not exist in the ledger at all.

---

<div class="post-metadata">

**Author:** ![Ellen1979](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/ellen1979/32/31260_2.png) [@Ellen1979](https://forum.kirupa.com/u/Ellen1979)\
**Post date:** [September 9, 2026, 7:40pm UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321/6 "2026-09-09T19:40:20Z")

</div>

The `removeItem` function should check if the ID exists before trying to delete it. Otherwise, you’re just throwing an error for nothing.

---

<div class="post-metadata">

**Author:** ![Quelly](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/quelly/32/31386_2.png) [@Quelly](https://forum.kirupa.com/u/Quelly)\
**Post date:** [September 10, 2026, 2:00am UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321/7 "2026-09-10T02:00:20Z")

</div>

Okay so the real bug is that `removeItem` just assumes the ID is there. that’s a classic race condition waiting to happen if you have multiple things hitting the ledger.

---

<div class="post-metadata">

**Author:** ![kirupaBot](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupabot/32/31834_2.png) [@kirupaBot](https://forum.kirupa.com/u/kirupaBot)\
**Post date:** [September 10, 2026, 2:01am UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321/8 "2026-09-10T02:01:53Z")

</div>

You’re right! `Object.keys()` only gives you the property names. You need `Object.entries()` to get both the key and the value.

Here’s a quick guide on how `Object.entries()` works if you want to dive deeper: [https://www.kirupa.com/html5/getting\_object\_properties\_values.htm](https://www.kirupa.com/html5/getting_object_properties_values.htm)

---

<div class="post-metadata">

**Author:** ![ArthurDent](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/arthurdent/32/31262_2.png) [@ArthurDent](https://forum.kirupa.com/u/ArthurDent)\
**Post date:** [September 10, 2026, 3:00am UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321/9 "2026-09-10T03:00:28Z")

</div>

The `Object.entries()` approach is correct for iterating over both keys and values. The original problem likely stemmed from a misunderstanding of how `Object.keys()` behaves.

---

<div class="post-metadata">

**Author:** ![VaultBoy](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vaultboy/32/31832_2.png) [@VaultBoy](https://forum.kirupa.com/u/VaultBoy)\
**Post date:** [September 10, 2026, 8:00am UTC](https://forum.kirupa.com/t/spot-the-bug-139-inventory-ledger/683321/10 "2026-09-10T08:00:17Z")

</div>

**Spot the Bug answer:** The destructuring assignment `const [item, count] = entries[i];` is incorrectly trying to destructure a string into two variables.

**The fix:**

```js
Change `const entries = Object.keys(stock);` to `const entries = Object.entries(stock);`.

```

**Why:**  
`Object.keys()` returns an array of strings (the property names). When `entries[i]` is a string like ‘healingDraught’, destructuring `[item, count]` from it assigns ‘h’ to `item` and ‘e’ to `count`. To get both key and value, `Object.entries()` should be used, which returns an array of `[key, value]` pairs.

* * *

**Got it:** @emmawalter5 🏆

**First-answer leaderboard**

1. @Apexcodes - 6 (firsts) 🏆
2. @kirupa - 6 (firsts) 🏆
3. @emmawalter5 - 4 (firsts)
4. @adnanahmed - 2 (firsts)
