langchain-ai/langchain · error · ValueError

Invalid token_counter shortcut '{token_counter}'. Available

Error message

Invalid token_counter shortcut '{token_counter}'. Available shortcuts: {available_shortcuts}.

What it means

Raised by `trim_messages` when `token_counter` is given as a string that is not in the `_TOKEN_COUNTER_SHORTCUTS` registry. String shortcuts exist for a small set of built-in token counters; any other string is rejected with the list of valid options in the message.

Source

Thrown at libs/core/langchain_core/messages/utils.py:1463

    if include_system and strategy == "first":
        msg = "include_system parameter is only valid with strategy='last'"
        raise ValueError(msg)

    messages = convert_to_messages(messages)

    # Handle string shortcuts for token counter
    if isinstance(token_counter, str):
        if token_counter in _TOKEN_COUNTER_SHORTCUTS:
            actual_token_counter = _TOKEN_COUNTER_SHORTCUTS[token_counter]
        else:
            available_shortcuts = ", ".join(
                f"'{key}'" for key in _TOKEN_COUNTER_SHORTCUTS
            )
            msg = (
                f"Invalid token_counter shortcut '{token_counter}'. "
                f"Available shortcuts: {available_shortcuts}."
            )
            raise ValueError(msg)
    else:
        # Type narrowing: at this point token_counter is not a str
        actual_token_counter = token_counter  # type: ignore[assignment]

    if hasattr(actual_token_counter, "get_num_tokens_from_messages"):
        list_token_counter = actual_token_counter.get_num_tokens_from_messages
    elif callable(actual_token_counter):
        if (
            next(
                iter(inspect.signature(actual_token_counter).parameters.values())
            ).annotation
            is BaseMessage
        ):

            def list_token_counter(messages: Sequence[BaseMessage]) -> int:
                return sum(actual_token_counter(msg) for msg in messages)  # type: ignore[arg-type, misc]

        else:

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Use one of the shortcuts listed in the error message exactly
  2. Or pass a callable: `token_counter=len` or a function `lambda msg: my_tokenizer(msg.content)`
  3. Or pass a model object that implements `get_num_tokens_from_messages`

Example fix

# before
trim_messages(msgs, max_tokens=500, token_counter='gpt4')

# after
trim_messages(msgs, max_tokens=500, token_counter=len)  # or a valid shortcut name from the error message
Defensive patterns

Strategy: validation

Validate before calling

from langchain_core.messages.utils import _TOKEN_COUNTER_SHORTCUTS

def valid_shortcut(name: str) -> bool:
    return name in _TOKEN_COUNTER_SHORTCUTS

if isinstance(token_counter, str) and not valid_shortcut(token_counter):
    token_counter = len  # or raise your own config error

Type guard

def is_trim_token_counter(tc: object) -> bool:
    if isinstance(tc, str):
        from langchain_core.messages.utils import _TOKEN_COUNTER_SHORTCUTS
        return tc in _TOKEN_COUNTER_SHORTCUTS
    return callable(tc) or hasattr(tc, 'get_num_tokens_from_messages')

Prevention

When it happens

Trigger: Calling `trim_messages(msgs, token_counter='gpt4')` when the shortcut is actually e.g. 'gpt-3.5-turbo'/'gpt-4o' style names defined in the registry; typos or provider names that were never registered.

Common situations: Assuming any model name works as a shortcut; using a shortcut removed or added in a different langchain-core version; copying a shortcut name from stale docs.

Understand the failure class

Related errors


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