boto/boto3 · error · RuntimeError

Cannot inject class attribute "{name}", attribute already ex

Error message

Cannot inject class attribute "{name}", attribute already exists in class dict.

What it means

`inject_attribute` is used during resource class generation to attach extra attributes (like `meta`, identifiers, or lazy-loaded properties) to a resource class's `class_attributes` dict. It refuses to overwrite an existing key to prevent silently shadowing a real method/attribute. A collision means the resource model defines an identifier, attribute, or action whose name clashes with something already declared on the class (e.g. a Python keyword, a reserved member like `meta`, or two model elements with the same name).

Source

Thrown at boto3/utils.py:64

    pass


def lazy_call(full_name, **kwargs):
    parent_kwargs = kwargs

    def _handler(**kwargs):
        module, function_name = full_name.rsplit('.', 1)
        module = import_module(module)
        kwargs.update(parent_kwargs)
        return getattr(module, function_name)(**kwargs)

    return _handler


def inject_attribute(class_attributes, name, value):
    if name in class_attributes:
        raise RuntimeError(
            f'Cannot inject class attribute "{name}", attribute '
            f'already exists in class dict.'
        )
    else:
        class_attributes[name] = value


class LazyLoadedWaiterModel:
    """A lazily loaded waiter model

    This does not load the service waiter model until an attempt is made
    to retrieve the waiter model for a specific waiter. This is helpful
    in docstring generation where we do not need to actually need to grab
    the waiter-2.json until it is accessed through a ``get_waiter`` call
    when the docstring is generated/accessed.
    """

    def __init__(self, bc_session, service_name, api_version):

View on GitHub (pinned to 6e10b029c1)

Solutions

  1. Upgrade boto3/botocore to a release where the model collision is resolved.
  2. Reinstall boto3 cleanly (`pip install --force-reinstall boto3`) to rule out a corrupt or patched data file.
  3. Remove any local monkey-patches or edited `resources-1.json` files that may have introduced the duplicate name.
  4. Report the collision (service + resource + attribute name) to the boto3 maintainers with the installed versions.

Example fix

# before: collision inside the bundled model for service X
import boto3
boto3.resource('svc-with-collision')  # RuntimeError: Cannot inject class attribute "..."

# after
pip install -U boto3 botocore   # pick a release that fixed the model
Defensive patterns

Strategy: type-guard

Validate before calling

import boto3
def resource_loads(service):
    try:
        boto3.resource(service)
        return True
    except RuntimeError:
        return False

# fail fast at startup so you can flag a reinstall instead of crashing later

Type guard

def model_collision_free(session, service) -> bool:
    try:
        session.resource(service)
        return True
    except RuntimeError:
        return False

Try / catch

try:
    handle = boto3.resource(service)
except RuntimeError as e:
    if 'Cannot inject class attribute' in str(e):
        handle = boto3.client(service)  # fall back to low-level client

Prevention

When it happens

Trigger: Generated resource class construction for a service whose `resources-1.json` declares two elements that resolve to the same Python name, or a name that collides with a base/reserved attribute (`meta`, `wait`, `load`, `reload`, a Python dunder). Surfaced on the first `boto3.resource(service)` instantiation that builds that class.

Common situations: A new API/model file introduced a name collision not yet fixed in your boto3 version; a locally patched resource model; running a beta/patched boto3 build; in rare cases, a service added a member whose name (after snake_case conversion) matches an existing one.

Related errors


AI-assisted analysis of boto/boto3@6e10b029c1 (2026-08-11). Data as JSON: /api/errors/2e316b5c6a8ae7ea. Report an issue: GitHub.