{"record":{"id":"4b2aae1d4095a095","repo":"langchain-ai/langchain","slug":"start-on-parameter-is-only-valid-with-strategy-la","errorCode":null,"errorMessage":"start_on parameter is only valid with strategy='last'","messagePattern":"start_on parameter is only valid with strategy='last'","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/messages/utils.py","lineNumber":1444,"sourceCode":"\n        ```python\n        [\n            SystemMessage(\"This is a 4 token text. The full message is 10 tokens.\"),\n            HumanMessage(\n                \"This is a 4 token text. The full message is 10 tokens.\",\n                id=\"first\",\n            ),\n            AIMessage(\n                [{\"type\": \"text\", \"text\": \"This is the FIRST 4 token block.\"}],\n                id=\"second\",\n            ),\n        ]\n        ```\n    \"\"\"\n    # Validate arguments\n    if start_on and strategy == \"first\":\n        msg = \"start_on parameter is only valid with strategy='last'\"\n        raise ValueError(msg)\n    if include_system and strategy == \"first\":\n        msg = \"include_system parameter is only valid with strategy='last'\"\n        raise ValueError(msg)\n\n    messages = convert_to_messages(messages)\n\n    # Handle string shortcuts for token counter\n    if isinstance(token_counter, str):\n        if token_counter in _TOKEN_COUNTER_SHORTCUTS:\n            actual_token_counter = _TOKEN_COUNTER_SHORTCUTS[token_counter]\n        else:\n            available_shortcuts = \", \".join(\n                f\"'{key}'\" for key in _TOKEN_COUNTER_SHORTCUTS\n            )\n            msg = (\n                f\"Invalid token_counter shortcut '{token_counter}'. \"\n                f\"Available shortcuts: {available_shortcuts}.\"\n            )","sourceCodeStart":1426,"sourceCodeEnd":1462,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/messages/utils.py#L1426-L1462","documentation":"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.","triggerScenarios":"Calling `trim_messages(msgs, strategy='first', start_on='human')`.","commonSituations":"Copying parameter sets between calls without adjusting for strategy; refactoring from last-window to first-window trimming and leaving `start_on` in place.","solutions":["Remove `start_on` when using `strategy='first'`","Or switch to `strategy='last'`, which supports `start_on` (and `include_system`)","Guard config-driven calls: only pass start_on/include_system when strategy == 'last'"],"exampleFix":"# before\ntrim_messages(msgs, max_tokens=500, strategy='first', start_on='human')\n\n# after\ntrim_messages(msgs, max_tokens=500, strategy='first')\n# or keep start_on with the supported strategy:\n# trim_messages(msgs, max_tokens=500, strategy='last', start_on='human')","handlingStrategy":"validation","validationCode":"kwargs = dict(max_tokens=500, strategy=strategy)\nif strategy == 'last':\n    kwargs['start_on'] = start_on\n    kwargs['include_system'] = include_system\ntrimmed = trim_messages(msgs, **kwargs)","typeGuard":"def start_on_allowed(strategy: str) -> bool:\n    return strategy == 'last'","tryCatchPattern":null,"preventionTips":["Only forward start_on when strategy == 'last'","Centralize trim_messages calls in one wrapper that knows the strategy-specific kwargs"],"tags":["trim-messages","argument-validation","context-window"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}