langchain-ai/langchain · error · ValueError

Could not resolve content_key {full_path!r}: expected a mapp

Error message

Could not resolve content_key {full_path!r}: expected a mapping at {current_path!r}, but found {type(content).__name__}.

What it means

`LangSmithLoader`'s `content_key` path resolver walks the example `inputs` mapping dot-segment by dot-segment; if an intermediate (or root) value along the path is not a `Mapping`, it raises `ValueError` reporting the full path, the offending segment position, and the actual type found. A too-deep or structurally wrong `content_key` is an invalid-argument error, deliberately unified with the missing-key case as `ValueError`.

Source

Thrown at libs/core/langchain_core/document_loaders/langsmith.py:165

        The extracted content value.

    Raises:
        ValueError: If a key in `content_key` is missing, or a value along the path
            (including `inputs` itself) is not a mapping.
    """
    content = inputs
    full_path = ".".join(content_key)

    for i, key in enumerate(content_key):
        current_path = ".".join(content_key[:i]) or "<root>"
        if not isinstance(content, Mapping):
            msg = (
                f"Could not resolve content_key {full_path!r}: expected a mapping at "
                f"{current_path!r}, but found {type(content).__name__}."
            )
            # A too-deep `content_key` is an invalid-argument error, not a runtime
            # type bug, so it is unified with the missing-key case as `ValueError`.
            raise ValueError(msg)  # noqa: TRY004
        if key not in content:
            msg = (
                f"Could not resolve content_key {full_path!r}: missing key {key!r} "
                f"under {current_path!r}."
            )
            raise ValueError(msg)
        content = content[key]

    return content


def _stringify(x: str | dict[str, Any]) -> str:
    if isinstance(x, str):
        return x
    try:
        return json.dumps(x, indent=2)
    except Exception:
        return str(x)

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Inspect one example first: `next(iter(Client().list_examples(dataset_name=...))).inputs` and shape content_key to that structure
  2. Remove a leading `inputs.` segment if your content_key is applied to the inputs mapping itself
  3. Ensure every intermediate step in the path is a dict; for lists, pre-transform the dataset or flatten in `format_content` instead of indexing via content_key
  4. If the schema changed, update or re-upload the dataset and align content_key

Example fix

# before
# example.inputs == {"messages": [{"text": "hi"}]}
loader = LangSmithLoader(dataset_name="ds", content_key="inputs.messages")

# after
loader = LangSmithLoader(dataset_name="ds", content_key="messages")
Defensive patterns

Strategy: validation

Validate before calling

from collections.abc import Mapping

def content_key_valid(inputs: dict, content_key: str) -> bool:
    node = inputs
    for seg in content_key.split('.'):
        if not isinstance(node, Mapping) or seg not in node:
            return False
        node = node[seg]
    return True

example_inputs = next(iter(client.list_examples(dataset_name=ds))).inputs
assert content_key_valid(example_inputs, content_key), 'bad content_key'

Type guard

from collections.abc import Mapping

def is_walkable_mapping(value: object) -> bool:
    """True if value can be traversed by a dotted content_key segment."""
    return isinstance(value, Mapping)

Try / catch

try:
    docs = list(loader.lazy_load())
except ValueError as e:
    if 'content_key' in str(e):
        raise ValueError(f'{dataset}: content_key {content_key!r} does not match schema; '
                         f'inspect one example's inputs') from e
    raise

Prevention

When it happens

Trigger: `LangSmithLoader(dataset_name=..., content_key='inputs.foo.bar')` where `inputs` is a string or `foo` is a list; dataset schemas where the key names fields (`inputs.inputs.msg`) but the actual root already is the inputs mapping (path should then be `msg`, not `inputs.msg`); numeric list indexing attempts like `content_key='messages.0.text'` (lists are not Mappings).

Common situations: Datasets whose example shape changed after a re-upload; guessing the content_key without inspecting one example; keys that start with the literal `inputs.` because docs show the stored example envelope rather than the passed mapping; trying to traverse arrays.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/8f0a804d3bb75c4e. Report an issue: GitHub.