celery/celery · error · KeyError

Key not found in first mapping: {key!r}

Error message

Key not found in first mapping: {key!r}

What it means

Raised by ChainMap.__delitem__ (collections.py:263) when you try to delete a key that is not present in the first mapping (the 'changes' layer). Celery's ChainMap only allows deletion of keys that live in the overrides map, since defaults layers are considered read-only. The error explicitly names 'first mapping' to point you at the changes dict.

Source

Thrown at celery/utils/collections.py:263

        # type: (Any) -> Any
        _key = self._key(key)
        for mapping in self.maps:
            try:
                return mapping[_key]
            except KeyError:
                pass
        return self.__missing__(key)

    def __setitem__(self, key, value):
        # type: (Any, Any) -> None
        self.changes[self._key(key)] = value

    def __delitem__(self, key):
        # type: (Any) -> None
        try:
            del self.changes[self._key(key)]
        except KeyError:
            raise KeyError(f'Key not found in first mapping: {key!r}')

    def clear(self):
        # type: () -> None
        self.changes.clear()

    def get(self, key, default=None):
        # type: (Any, Any) -> Any
        try:
            return self[self._key(key)]
        except KeyError:
            return default

    def __len__(self):
        # type: () -> int
        return len(set().union(*self.maps))

    def __iter__(self):
        return self._iterate_keys()

View on GitHub (pinned to 571efe8120)

Solutions

  1. Check 'KEY' in the changes/overrides layer before deleting, or use pop(key, None) semantics.
  2. Re-set the key to its default value instead of deleting it if it lives in defaults.
  3. Confirm the key actually lives in app.conf (the changes view) with 'KEY' in app.conf before del.

Example fix

# before
del app.conf['task_serializer']

# after
if 'task_serializer' in app.conf:
    del app.conf['task_serializer']
Defensive patterns

Strategy: validation

Validate before calling

if key in conf.changes:
    del conf[key]

Type guard

def key_in_changes(conf, key: str) -> bool:
    return key in conf.changes

Try / catch

try:
    del conf[key]
except KeyError as e:
    pass  # already absent

Prevention

When it happens

Trigger: Calling del conf['SOME_KEY'] or chainmap.pop-related deletion when the key exists only in a defaults layer, or doesn't exist at all. Also triggered by ConfigurationView.__delitem__ falling through to ChainMap when the key was never set in changes.

Common situations: Attempting to 'unset' a setting that came from celery defaults or a config_from_object module rather than from runtime overrides. Cleanup code that assumes a key was previously set during a test.

Related errors


AI-assisted analysis of celery/celery@571efe8120 (2026-08-04). Data as JSON: /data/errors/067b4d03b1ba5e9c.json. Report an issue: GitHub.