BadRequestError: 400 Missing required parameter: 'messages[3].content[0].type'. when tool returns array of objects #93

Closed
opened 2026-02-15 17:15:38 -05:00 by yindo · 9 comments
Owner

Originally created by @brianpursley on GitHub (Sep 23, 2024).

Originally assigned to: @bracesproul on GitHub.

I'm getting the error BadRequestError: 400 Missing required parameter: 'messages[3].content[0].type' when calling a custom tool that returns an array.

However, if I wrap it in an object, I do not get an error and it succeeds (see the examples below).

It would be good for tools to support returning an array. But if that isn't possible, it would be helpful to have a more informative error, maybe something like BadRequestError: 400 Invalid return type: array is not a supported return type.


This tool fails:

import {tool} from "@langchain/core/tools";
import {PrismaClient} from "@prisma/client";

const prisma = new PrismaClient()

export const getClipsterCategories =
    tool(async () => {
        const categories = await prisma.category.findMany()
        return categories
    }, {
        name: "getClipsterCategories",
        description: "Gets product categories from the Clipster database."
    })

This tool succeeds:

import {tool} from "@langchain/core/tools";
import {PrismaClient} from "@prisma/client";

const prisma = new PrismaClient()

export const getClipsterCategories =
    tool(async () => {
        const categories = await prisma.category.findMany()
        return {
            categories
        }
    }, {
        name: "getClipsterCategories",
        description: "Gets product categories from the Clipster database."
    })

Error Details:

BadRequestError: 400 Missing required parameter: 'messages[3].content[0].type'.
    at APIError.generate (webpack-internal:///(rsc)/./node_modules/openai/error.mjs:60:20)
    at OpenAI.makeStatusError (webpack-internal:///(rsc)/./node_modules/openai/core.mjs:304:65)
    at OpenAI.makeRequest (webpack-internal:///(rsc)/./node_modules/openai/core.mjs:347:30)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async eval (webpack-internal:///(rsc)/./node_modules/@langchain/openai/dist/chat_models.js:1378:29)
    at async RetryOperation.eval [as _fn] (webpack-internal:///(rsc)/./node_modules/p-retry/index.js:50:12) {
  status: 400,
  headers: {
    'access-control-expose-headers': 'X-Request-ID',
    'cf-cache-status': 'DYNAMIC',
    'cf-ray': '<REDACTED>',
    connection: 'keep-alive',
    'content-length': '219',
    'content-type': 'application/json',
    date: 'Mon, 23 Sep 2024 14:41:43 GMT',
    'openai-organization': 'user-<REDACTED>',
    'openai-processing-ms': '20',
    'openai-version': '2020-10-01',
    server: 'cloudflare',
    'set-cookie': '__cf_bm=<REDACTED>; path=/; expires=Mon, 23-Sep-24 15:11:43 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None, _cfuvid=i<REDACTED>; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None',
    'strict-transport-security': 'max-age=15552000; includeSubDomains; preload',
    'x-content-type-options': 'nosniff',
    'x-ratelimit-limit-requests': '10000',
    'x-ratelimit-limit-tokens': '200000',
    'x-ratelimit-remaining-requests': '9998',
    'x-ratelimit-remaining-tokens': '199956',
    'x-ratelimit-reset-requests': '16.106s',
    'x-ratelimit-reset-tokens': '13ms',
    'x-request-id': 'req_<REDACTED>'
  },
  request_id: 'req_<REDACTED>',
  error: {
    message: "Missing required parameter: 'messages[3].content[0].type'.",
    type: 'invalid_request_error',
    param: 'messages[3].content[0].type',
    code: 'missing_required_parameter'
  },
  code: 'missing_required_parameter',
  param: 'messages[3].content[0].type',
  type: 'invalid_request_error',
  attemptNumber: 1,
  retriesLeft: 6,
  pregelTaskId: '<REDACTED>'
}
Originally created by @brianpursley on GitHub (Sep 23, 2024). Originally assigned to: @bracesproul on GitHub. I'm getting the error `BadRequestError: 400 Missing required parameter: 'messages[3].content[0].type'` when calling a custom tool that returns an array. However, if I wrap it in an object, I do not get an error and it succeeds (see the examples below). It would be good for tools to support returning an array. But if that isn't possible, it would be helpful to have a more informative error, maybe something like `BadRequestError: 400 Invalid return type: array is not a supported return type`. --- #### This tool fails: ```typescript import {tool} from "@langchain/core/tools"; import {PrismaClient} from "@prisma/client"; const prisma = new PrismaClient() export const getClipsterCategories = tool(async () => { const categories = await prisma.category.findMany() return categories }, { name: "getClipsterCategories", description: "Gets product categories from the Clipster database." }) ``` #### This tool succeeds: ```typescript import {tool} from "@langchain/core/tools"; import {PrismaClient} from "@prisma/client"; const prisma = new PrismaClient() export const getClipsterCategories = tool(async () => { const categories = await prisma.category.findMany() return { categories } }, { name: "getClipsterCategories", description: "Gets product categories from the Clipster database." }) ``` --- #### Error Details: ``` BadRequestError: 400 Missing required parameter: 'messages[3].content[0].type'. at APIError.generate (webpack-internal:///(rsc)/./node_modules/openai/error.mjs:60:20) at OpenAI.makeStatusError (webpack-internal:///(rsc)/./node_modules/openai/core.mjs:304:65) at OpenAI.makeRequest (webpack-internal:///(rsc)/./node_modules/openai/core.mjs:347:30) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async eval (webpack-internal:///(rsc)/./node_modules/@langchain/openai/dist/chat_models.js:1378:29) at async RetryOperation.eval [as _fn] (webpack-internal:///(rsc)/./node_modules/p-retry/index.js:50:12) { status: 400, headers: { 'access-control-expose-headers': 'X-Request-ID', 'cf-cache-status': 'DYNAMIC', 'cf-ray': '<REDACTED>', connection: 'keep-alive', 'content-length': '219', 'content-type': 'application/json', date: 'Mon, 23 Sep 2024 14:41:43 GMT', 'openai-organization': 'user-<REDACTED>', 'openai-processing-ms': '20', 'openai-version': '2020-10-01', server: 'cloudflare', 'set-cookie': '__cf_bm=<REDACTED>; path=/; expires=Mon, 23-Sep-24 15:11:43 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None, _cfuvid=i<REDACTED>; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None', 'strict-transport-security': 'max-age=15552000; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'x-ratelimit-limit-requests': '10000', 'x-ratelimit-limit-tokens': '200000', 'x-ratelimit-remaining-requests': '9998', 'x-ratelimit-remaining-tokens': '199956', 'x-ratelimit-reset-requests': '16.106s', 'x-ratelimit-reset-tokens': '13ms', 'x-request-id': 'req_<REDACTED>' }, request_id: 'req_<REDACTED>', error: { message: "Missing required parameter: 'messages[3].content[0].type'.", type: 'invalid_request_error', param: 'messages[3].content[0].type', code: 'missing_required_parameter' }, code: 'missing_required_parameter', param: 'messages[3].content[0].type', type: 'invalid_request_error', attemptNumber: 1, retriesLeft: 6, pregelTaskId: '<REDACTED>' } ```
yindo added the bug label 2026-02-15 17:15:38 -05:00
yindo closed this issue 2026-02-15 17:15:38 -05:00
Author
Owner

@jacoblee93 commented on GitHub (Sep 23, 2024):

Yes definitely - it should be allowed, will investigate.

@jacoblee93 commented on GitHub (Sep 23, 2024): Yes definitely - it should be allowed, will investigate.
Author
Owner

@brianpursley commented on GitHub (Sep 23, 2024):

OK thanks.

To simplify the example, here is a repro without involving Prisma:

This fails:

import {tool} from "@langchain/core/tools";

export const getClipsterCategories =
    tool(() => [
        {id: "c1", name: "foo"},
        {id: "c2", name: "bar"}
    ], {
        name: "getClipsterCategories",
        description: "Gets product categories from the Clipster database."
    })

This succeeds:

import {tool} from "@langchain/core/tools";

export const getClipsterCategories =
    tool(() => ({
        categories: [
            {id: "c1", name: "foo"},
            {id: "c2", name: "bar"}
        ]
    }), {
        name: "getClipsterCategories",
        description: "Gets product categories from the Clipster database."
    })

Interestingly, if it is a simple string array, it succeeds. It only seems to fail if it is an array of objects.

This succeeds:

import {tool} from "@langchain/core/tools";

export const getClipsterCategories =
    tool(() => ["foo", "bar"], {
        name: "getClipsterCategories",
        description: "Gets product categories from the Clipster database."
    })
@brianpursley commented on GitHub (Sep 23, 2024): OK thanks. To simplify the example, here is a repro without involving Prisma: #### This fails: ```typescript import {tool} from "@langchain/core/tools"; export const getClipsterCategories = tool(() => [ {id: "c1", name: "foo"}, {id: "c2", name: "bar"} ], { name: "getClipsterCategories", description: "Gets product categories from the Clipster database." }) ``` #### This succeeds: ```typescript import {tool} from "@langchain/core/tools"; export const getClipsterCategories = tool(() => ({ categories: [ {id: "c1", name: "foo"}, {id: "c2", name: "bar"} ] }), { name: "getClipsterCategories", description: "Gets product categories from the Clipster database." }) ``` --- Interestingly, if it is a simple string array, it succeeds. It only seems to fail if it is an array of objects. #### This succeeds: ```typescript import {tool} from "@langchain/core/tools"; export const getClipsterCategories = tool(() => ["foo", "bar"], { name: "getClipsterCategories", description: "Gets product categories from the Clipster database." }) ```
Author
Owner

@jacoblee93 commented on GitHub (Sep 23, 2024):

Got it - for now, does stringifying the output work?

It should get passed to the LLM fine that way too.

@jacoblee93 commented on GitHub (Sep 23, 2024): Got it - for now, does stringifying the output work? It should get passed to the LLM fine that way too.
Author
Owner

@brianpursley commented on GitHub (Sep 23, 2024):

does stringifying the output work?

Yes, stringifying the result works.

@brianpursley commented on GitHub (Sep 23, 2024): > does stringifying the output work? Yes, stringifying the result works.
Author
Owner

@surnr commented on GitHub (Dec 19, 2024):

I'm facing problem like this
raise self._make_status_error_from_response(err.response) from None openai.BadRequestError: Error code: 400 - {'error': {'message': "Missing required parameter: 'messages[3].content[0].type'.", 'type': 'invalid_request_error', 'param': 'messages[3].content[0].type', 'code': 'missing_required_parameter'}}

While converting a json of tool call to ToolCall Object

@surnr commented on GitHub (Dec 19, 2024): I'm facing problem like this `raise self._make_status_error_from_response(err.response) from None openai.BadRequestError: Error code: 400 - {'error': {'message': "Missing required parameter: 'messages[3].content[0].type'.", 'type': 'invalid_request_error', 'param': 'messages[3].content[0].type', 'code': 'missing_required_parameter'}}` While converting a json of tool call to ToolCall Object
Author
Owner

@YJack0000 commented on GitHub (Dec 20, 2024):

Facing the same problem when using langchain

@YJack0000 commented on GitHub (Dec 20, 2024): Facing the same problem when using langchain
Author
Owner

@dannyb648 commented on GitHub (Dec 26, 2024):

I'm having this exact issue aswell - the work around in the short term is just to JSON.stringify() the data. I can't work out what causes this issue however - some of my tools work fine with an array response, some do not.

@dannyb648 commented on GitHub (Dec 26, 2024): I'm having this exact issue aswell - the work around in the short term is just to JSON.stringify() the data. I can't work out what causes this issue however - some of my tools work fine with an array response, some do not.
Author
Owner

@jacoblee93 commented on GitHub (Dec 26, 2024):

Sorry, forgot to follow up. I believe this is a consequence of how we handle artifacts in core:

https://js.langchain.com/docs/how_to/tool_artifacts

We should definitely clean this up in the next breaking release CC @baskaryan

@jacoblee93 commented on GitHub (Dec 26, 2024): Sorry, forgot to follow up. I believe this is a consequence of how we handle artifacts in core: https://js.langchain.com/docs/how_to/tool_artifacts We should definitely clean this up in the next breaking release CC @baskaryan
Author
Owner

@dqbd commented on GitHub (Sep 9, 2025):

I believe this should be already solved. Closing this issue

@dqbd commented on GitHub (Sep 9, 2025): I believe this should be already solved. Closing this issue
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraphjs#93