KeyNotFoundException: The given key was not present in the dictionary

ConsoleRuntime exception · Scripting

KeyNotFoundException: The given key was not present in the dictionary.

Your code read dictionary[key] for a key the dictionary does not contain. The indexer throws instead of returning a default, so any lookup that can miss needs a check.

Read the Console line first

The stack trace names the script and line of the lookup. Newer runtimes include the key in the message; if yours does not, log the key just before the line.

Common causes

  1. The lookup runs before the dictionary is filled

    One script fills the dictionary in Start while another reads it in Awake or its own Start, and the reader happens to run first. Fill shared lookups in Awake and read them in Start or later.

  2. The key differs slightly

    String keys are compared exactly: "Sword", "sword" and "Sword " are three different keys. Item IDs typed by hand in the Inspector are a common source.

  3. The entry was removed or the dictionary rebuilt

    Clearing and refilling a dictionary, for example on scene load, leaves a window where lookups miss.

The fix

Fix
C#
if (items.TryGetValue(itemId, out ItemData item))
{
    Equip(item);
}
else
{
    Debug.LogWarning($"No item with id '{itemId}'", this);
}

Stop it coming back

Use TryGetValue wherever a key might be missing, and make IDs data rather than hand-typed strings: an enum, or a reference to a ScriptableObject asset, cannot be misspelled.

Questions

Why does a dictionary throw when a List returns nothing?
The dictionary indexer is designed to throw on a missing key so a bug is not hidden. Use TryGetValue when a missing key is normal, and the indexer only when the key must exist.
Can I see a Dictionary in the Inspector?
Unity does not serialize Dictionary. Serialize a list of key and value pairs instead and build the dictionary from it in Awake.
How do I add or replace a value without errors?
Assigning dict[key] = value adds the key or replaces its value. dict.Add(key, value) throws if the key already exists, and TryAdd returns false instead.

Scripts that avoid it

Related errors

Got a different error? Paste it into the error lookup.