langchain-ai/langchain · error · ValueError

start_on parameter is only valid with strategy='last'

Error message

start_on parameter is only valid with strategy='last'

What it means

Raised by `trim_messages` at argument validation: `start_on` (constrain which role the kept window may start on) is only implemented for `strategy='last'`. With `strategy='first'` the parameter is rejected before any trimming happens.

Source

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

        ```python
        [
            SystemMessage("This is a 4 token text. The full message is 10 tokens."),
            HumanMessage(
                "This is a 4 token text. The full message is 10 tokens.",
                id="first",
            ),
            AIMessage(
                [{"type": "text", "text": "This is the FIRST 4 token block."}],
                id="second",
            ),
        ]
        ```
    """
    # Validate arguments
    if start_on and strategy == "first":
        msg = "start_on parameter is only valid with strategy='last'"
        raise ValueError(msg)
    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}."
            )

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Remove `start_on` when using `strategy='first'`
  2. Or switch to `strategy='last'`, which supports `start_on` (and `include_system`)
  3. Guard config-driven calls: only pass start_on/include_system when strategy == 'last'

Example fix

# before
trim_messages(msgs, max_tokens=500, strategy='first', start_on='human')

# after
trim_messages(msgs, max_tokens=500, strategy='first')
# or keep start_on with the supported strategy:
# trim_messages(msgs, max_tokens=500, strategy='last', start_on='human')
Defensive patterns

Strategy: validation

Validate before calling

kwargs = dict(max_tokens=500, strategy=strategy)
if strategy == 'last':
    kwargs['start_on'] = start_on
    kwargs['include_system'] = include_system
trimmed = trim_messages(msgs, **kwargs)

Type guard

def start_on_allowed(strategy: str) -> bool:
    return strategy == 'last'

Prevention

When it happens

Trigger: Calling `trim_messages(msgs, strategy='first', start_on='human')`.

Common situations: Copying parameter sets between calls without adjusting for strategy; refactoring from last-window to first-window trimming and leaving `start_on` in place.

Related errors


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