Skip to content

titleMethod structured/functions forces tool_choice, which current Claude models reject with 400 #576

Description

@danny-avila

Summary

titleMethod: structured and titleMethod: functions build the title chain with model.withStructuredOutput(schema) (src/utils/title.ts). For ChatAnthropic the default method is functionCalling, which — unless thinking.type is enabled/adaptive — binds the schema as a tool and forces it with tool_choice: { type: "tool", name } (@langchain/anthropic 1.5.2, chat_models.js withStructuredOutput).

Current Claude models no longer accept forced tool use, so any title model in that family fails with a 400 and the conversation never gets a title.

Observed on @librechat/agents 3.8.6 / @langchain/anthropic 1.5.2.

Reproduction

Direct API probe, same request against three models:

{
  "tools": [{ "name": "extract", "description": "Extract a title", "input_schema": { "type": "object", "properties": { "title": { "type": "string" } }, "required": ["title"] } }],
  "tool_choice": { "type": "tool", "name": "extract" },
  "messages": [{ "role": "user", "content": "Title this: a chat about node versions" }]
}
model result
claude-haiku-4-5 200, tool_use block
claude-opus-5-5 400 tool_choice: type "tool" and "any" are not supported for this model.
claude-fable-5-1 400 tool_choice: type "tool" and "any" are not supported for this model.

In @librechat/agents, configure a title model from the second or third row with titleMethod: 'structured' (or 'functions') and run generateTitle; the structured chain returns the same 400.

Where it happens

  • src/utils/title.ts → createTitleRunnable: model.withStructuredOutput(titleSchema) / combinedSchema, no method option.
  • @langchain/anthropic withStructuredOutput, method === "functionCalling" branch: when this.thinking?.type is not enabled/adaptive, it sets tool_choice: { type: "tool", name: functionName }. Title models are normally created with thinking off, so this is the branch taken.
  • When thinking is enabled/adaptive the other branch is taken: no forced tool_choice, but raiseIfNoToolCalls throws if the model answers in text — so the structured title path is fragile either way on these models.

Expected

The structured/functions title methods should work on models that have retired forced tool use. Options, roughly in order of preference:

  1. In createTitleRunnable, pass { method: 'jsonSchema' } for Anthropic models that support structured outputs (output_format / json_schema), which needs no tool_choice.
  2. Otherwise bind the schema as a tool with tool_choice: { type: 'auto' } plus a prompt instruction to call it, and fall back to the completion title path when no tool call is returned, instead of surfacing the 400.
  3. At minimum, detect the provider error (tool_choice: type "tool" and "any" are not supported) and fall back to TitleMethod.COMPLETION rather than failing the title.

titleMethod: completion is unaffected and is the workaround today.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions