Skip to content

convertMessagesToResponsesInput does not correctly handle messages with string content. Throws error: content.findIndex is not a function #10565

@sflanker

Description

Checked other resources

  • This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
  • I added a very descriptive title to this issue.
  • I searched the LangChain.js documentation with the integrated search.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain.js rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).

Example Code

Invoke a ReactAgent that uses the OpenAI Responses API (instantiated with createAgent) with a messages list that includes an AIMessage constructed like this: new AIMessage('plain text of response')

I can write an actual complete example but I think the source of this defect is self evident (see Description).

Error Message and Stack Trace (if applicable)

TypeError: content.findIndex is not a function
    at /node_modules/@langchain/openai/src/converters/responses.ts:1511:37
    at iife (/node_modules/@langchain/openai/src/utils/misc.ts:9:41)
    at /node_modules/@langchain/openai/src/converters/responses.ts:1510:20
    at Array.flatMap (<anonymous>)
    at convertMessagesToResponsesInput (/node_modules/@langchain/openai/src/converters/responses.ts:1313:19)
    at ChatOpenAIResponses._streamResponseChunks (/node_modules/@langchain/openai/src/chat_models/responses.ts:241:16)
    at _streamResponseChunks.next (<anonymous>)
    at ChatOpenAIResponses._generate (/node_modules/@langchain/openai/src/chat_models/responses.ts:183:24)
    at ChatOpenAI._generate (/node_modules/@langchain/openai/src/chat_models/index.ts:674:29)
    at /node_modules/@langchain/core/src/language_models/chat_models.ts:568:46
    at Array.map (<anonymous>)
    at ImageToolResponseHandlerModelWrapper._generateUncached (/node_modules/@langchain/core/src/language_models/chat_models.ts:567:22)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at baseHandler (/node_modules/langchain/src/agents/nodes/AgentNode.ts:369:25)
    at AgentNode.#invokeModel (/node_modules/langchain/src/agents/nodes/AgentNode.ts:656:22)
    at AgentNode.#run (/node_modules/langchain/src/agents/nodes/AgentNode.ts:235:7)
    at AgentNode.invoke (/node_modules/langchain/src/agents/RunnableCallable.ts:71:25)
    at RunnableSequence.invoke (/node_modules/@langchain/core/src/runnables/base.ts:1912:25)
    at _runWithRetry (/node_modules/@langchain/langgraph/src/pregel/retry.ts:103:16)
    at PregelRunner._executeTasksWithRetry (/node_modules/@langchain/langgraph/src/pregel/runner.ts:330:27)

Description

This issue was introduced when the phase property was implemented: https://github.com/langchain-ai/langchainjs/pull/10509/changes#diff-927d808cb2e39b11bbec738a6feaff447122233b5b0d542a042abc2ca81560a9R1510

This code is pretty obviously incorrect given that other parts of that same function perform type gaurds and handle the case were content is a string. The confusion was introduced earlier when this change f97b488#diff-927d808cb2e39b11bbec738a6feaff447122233b5b0d542a042abc2ca81560a9R1122-R1125 added an incorrect type cast as { content: ContentBlock[] }.

The type definition of BaseMessage declares content to be `` which may be a string or an array when using the default generic type parameters (which this code does):

export type $InferMessageContent<
  TStructure extends MessageStructure,
  TRole extends MessageType,
> = TRole extends "tool"
  ? // For tool messages, infer content from tool output types if available
    $InferToolOutputs<TStructure> extends infer TOutput
    ? [TOutput] extends [never]
      ? string | Array<ContentBlock | ContentBlock.Text>
      : [unknown] extends [TOutput]
        ? // Fallback to default when TOutput is unknown (no specific tools defined)
            string | Array<ContentBlock | ContentBlock.Text>
        : TOutput | string | Array<ContentBlock | ContentBlock.Text>
    : string | Array<ContentBlock | ContentBlock.Text>
  : TStructure["outputVersion"] extends "v1"
    ? Array<$InferMessageContentBlocks<TStructure, TRole>>
    : string | Array<ContentBlock | ContentBlock.Text>;

in this case TRole is not "tool" and MessageStructure["outputVersion"] is "v0" by default. so the correct type for content is string | Array<ContentBlock | ContentBlock.Text>

System Info

MacOS 14.7.5
langchain 1.2.39
@langchain/openai 1.4.1
node v20.19.0
npm 10.8.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions