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:
- In
createTitleRunnable, pass { method: 'jsonSchema' } for Anthropic models that support structured outputs (output_format / json_schema), which needs no tool_choice.
- 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.
- 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.
Summary
titleMethod: structuredandtitleMethod: functionsbuild the title chain withmodel.withStructuredOutput(schema)(src/utils/title.ts). ForChatAnthropicthe default method isfunctionCalling, which — unlessthinking.typeisenabled/adaptive— binds the schema as a tool and forces it withtool_choice: { type: "tool", name }(@langchain/anthropic1.5.2,chat_models.jswithStructuredOutput).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/agents3.8.6 /@langchain/anthropic1.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" }] }claude-haiku-4-5tool_useblockclaude-opus-5-5tool_choice: type "tool" and "any" are not supported for this model.claude-fable-5-1tool_choice: type "tool" and "any" are not supported for this model.In
@librechat/agents, configure a title model from the second or third row withtitleMethod: 'structured'(or'functions') and rungenerateTitle; the structured chain returns the same 400.Where it happens
src/utils/title.ts→createTitleRunnable:model.withStructuredOutput(titleSchema)/combinedSchema, nomethodoption.@langchain/anthropicwithStructuredOutput,method === "functionCalling"branch: whenthis.thinking?.typeis notenabled/adaptive, it setstool_choice: { type: "tool", name: functionName }. Title models are normally created with thinking off, so this is the branch taken.tool_choice, butraiseIfNoToolCallsthrows 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:
createTitleRunnable, pass{ method: 'jsonSchema' }for Anthropic models that support structured outputs (output_format/json_schema), which needs notool_choice.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.tool_choice: type "tool" and "any" are not supported) and fall back toTitleMethod.COMPLETIONrather than failing the title.titleMethod: completionis unaffected and is the workaround today.