boto/boto3 · error · NotImplementedError

Unsupported source type

Error message

Unsupported source type: {source}

What it means

Raised by the resource factory when building a resource's response from its identifier model. Each identifier declares a `source` describing where its value comes from, and only four values are supported: `requestParameter`, `identifier`, `data`, and `input`. Any other value means the bundled resource model JSON is malformed or incompatible with this boto3 version. Users almost never hit this through their own code; it signals a broken or mismatched installation.

Solutions

  1. Reinstall boto3 cleanly: `pip install --force-reinstall boto3` so boto3 and botocore are re-paired to compatible versions.
  2. Pin a known-good boto3/botocore pair in requirements.txt (e.g. `boto3==X.Y.Z botocore==X.Y.Z`) and reinstall.
  3. Remove any local edits or monkey-patches to `boto3/data/<service>/resources-1.json` and any custom resource loader hooks.
  4. Verify the file isn't corrupt: `python -c "import boto3; boto3.resource('s3')"` in a fresh virtualenv to isolate environment-specific breakage.

Example fix

# before: mismatched versions after a partial upgrade
#   pip install --upgrade botocore   (left boto3 stale)
import boto3
boto3.resource('ec2').instances.all()  # raises NotImplementedError: Unsupported source type

# after
pip install --force-reinstall --no-cache-dir boto3
Defensive patterns

Strategy: type-guard

Validate before calling

import boto3, botocore
# Ensure a coherent pair before using resources
assert boto3.__version__ and botocore.__version__
# Smoke-test the resource model loads
try:
    boto3.resource('s3')
except NotImplementedError as e:
    print('boto3/botocore model mismatch:', e)

Type guard

def safe_resource(session, service_name):
    try:
        return session.resource(service_name)
    except NotImplementedError:
        # fall back to client; reinstall flagged elsewhere
        return session.client(service_name)

Try / catch

try:
    res = boto3.resource('ec2')
except NotImplementedError:
    # reinstall boto3, then retry once; do not silently swallow

Prevention

When it happens

Trigger: A service's `resources-1.json` defines an identifier whose `source` field is something other than `requestParameter`/`identifier`/`data`/`input`. Occurs after `boto3.resource(...)` and a subsequent load/action on that resource triggers `build_identified_keywords`/response processing in `boto3/resources/response.py`.

Common situations: boto3 and botocore installed at incompatible versions (e.g. downgrading one without the other), a corrupted/partially-removed package install, a locally patched or hand-edited resource model under `boto3/data/`, or a third-party plugin that injects non-standard resource definitions.

Related errors


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

Appendix: source

Thrown at boto3/resources/response.py:71

    for identifier in identifiers:
        source = identifier.source
        target = identifier.target

        if source == 'response':
            value = jmespath.search(identifier.path, raw_response)
        elif source == 'requestParameter':
            value = jmespath.search(identifier.path, params)
        elif source == 'identifier':
            value = getattr(parent, xform_name(identifier.name))
        elif source == 'data':
            # If this is a data member then it may incur a load
            # action before returning the value.
            value = get_data_member(parent, identifier.path)
        elif source == 'input':
            # This value is set by the user, so ignore it here
            continue
        else:
            raise NotImplementedError(f'Unsupported source type: {source}')

        results.append((xform_name(target), value))

    return results


def build_empty_response(search_path, operation_name, service_model):
    """
    Creates an appropriate empty response for the type that is expected,
    based on the service model's shape type. For example, a value that
    is normally a list would then return an empty list. A structure would
    return an empty dict, and a number would return None.

    :type search_path: string
    :param search_path: JMESPath expression to search in the response
    :type operation_name: string
    :param operation_name: Name of the underlying service operation.
    :type service_model: :ref:`botocore.model.ServiceModel`

View on GitHub (pinned to 6e10b029c1)