Skip to content

ProviderStrategy parses Gemini thought summaries as structured output #11435

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

import { AIMessage, providerStrategy } from "langchain";
import { z } from "zod";

const Response = z.object({ result: z.string() });
const message = new AIMessage({
  content: [
    {
      text: "A returned thought summary.",
      thought: true,
      type: "text",
    },
    {
      text: JSON.stringify({
        result: "Structured response.",
      } satisfies z.infer<typeof Response>),
      type: "text",
    },
  ],
});

console.log(providerStrategy(Response).parse(message));
// Expected: { result: "Structured response." }
// Actual: undefined

Error Message and Stack Trace (if applicable)

Failed to parse structured output for tool 'providerStrategy':
  - Model output did not satisfy the provided response schema.

Description

@langchain/google represents a Gemini thought summary as a text content block with thought: true, followed by the structured JSON block.

ProviderStrategy.parse() selects the first text block, attempts to parse the thought summary as JSON, and returns undefined. It should ignore thought blocks when selecting the structured response.

The text-block selection logic was introduced by #9623 in ade8b8a, released in langchain@1.1.6. That change added support for array content by selecting the first text block, assuming reasoning used a distinct block type. @langchain/google can instead represent a Gemini thought as { type: "text", thought: true }.

The selection predicate should exclude thought blocks:

 block.type === "text" &&
+!("thought" in block && block.thought === true) &&
 "text" in block

I have a local pnpm patch which resolves this issue and I'm happy to open a PR if needed.

System Info

$ pnpm info @langchain/google
@langchain/google@0.2.3 | MIT | deps: 3 | versions: 27
Google integrations for LangChain.js
https://github.com/langchain-ai/langchainjs#readme

dist
.tarball: https://registry.npmjs.org/@langchain/google/-/google-0.2.3.tgz
.shasum: b888257fa7e65b8964b535c930604348be55618b
.integrity: sha512-5X7SwP+oE+C7Jh+X67yFBLm7G7d1ZsJJKC76UNI4MZzWAC5ZtC+JVXCY+Ehj4w3Pr9XxHxc6IwBmQl5SG39yOg==
.unpackedSize: 1.05 MB

dependencies:
eventsource-parser: ^3.1.0, google-auth-library: ^10.9.1, jose: ^6.2.4

maintainers:
- lc-oss-admin <oss-admin@langchain.dev>
- langchain-security <infra@langchain.dev>

dist-tags:
dev: 0.1.7-dev-1773962633795
latest: 0.2.3

published 1 day ago by GitHub Actions <npm-oidc-no-reply@github.com>

$ pnpm info langchain
langchain@1.5.10 | MIT | deps: 4 | versions: 463
Typescript bindings for langchain
https://github.com/langchain-ai/langchainjs/tree/main/libs/langchain/

keywords: llm, ai, gpt3, chain, prompt, prompt engineering, chatgpt, machine learning, ml, openai, embeddings, vectorstores

dist
.tarball: https://registry.npmjs.org/langchain/-/langchain-1.5.10.tgz
.shasum: 197c69869a458c6a695852084e7f817a54b22d2b
.integrity: sha512-JaC12C1qyGn985vvjttr4hr8lfFzWhrXp2M1byZJGmNJ2RiIgqnhiYDuLlG/xHDxhKD3onJ5pCuUif/cbdqPhA==
.unpackedSize: 3.23 MB

dependencies:
zod: ^3.25.76 || ^4, langsmith: >=0.5.0 <1.0.0, @langchain/langgraph: ^1.4.10, @langchain/langgraph-checkpoint: ^1.1.5

maintainers:
- hntrl <hunter@hntrl.io>
- lc-oss-admin <oss-admin@langchain.dev>

dist-tags:
tag-for-publishing-older-releases: 0.2.20
alpha: 1.0.0-alpha.9
next: 1.0.0-alpha.9
dev: 1.5.1-dev-1781824996270
latest: 1.5.10

published 1 day ago by GitHub Actions <npm-oidc-no-reply@github.com>

$ node -v
v24.15.0

Windows + WSL2.

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