Skip to content

[Docs] expressHandler requires undocumented "data" key in request body, causing difficult-to-debug errors #3836

@andreamartelli

Description

@andreamartelli

The expressHandler and startFlowServer functions in @genkit-ai/express require the request body to be a JSON object with a top-level key named "data". The value of this "data" key is then used as the input for the flow.

This requirement is not documented, and because there are no curl or request body examples on the Express.js integration page, it is impossible for a user to know the correct request format.

This leads to persistent INVALID_ARGUMENT errors with the message Provided data: undefined, which are extremely difficult to debug, as standard requests appear to be parsed correctly by the Express json() middleware.

Problem:

Upon inspecting the source code for the expressHandler function, the handler explicitly expects the flow's input to be located at request.body.data:

// from @genkit-ai/express/lib/express.js (line 64)
// https://github.com/firebase/genkit/blob/72fa4eaf32839b22151ecf78a732ec8281869914/js/plugins/express/src/index.ts#L64
const input = request.body.data as z.infer<I>;

A user attempting to call a flow endpoint with a standard and logical request body, such as sending the flow's input object directly, will inevitably fail.

To Reproduce:

  1. Define a flow with an input schema, e.g., z.object({ question: z.string() }).
  2. Expose this flow using startFlowServer (or expressHandler directly).
  3. Call the endpoint with a logically structured request body:
    # This logical request will fail
    curl -X POST -H "Content-Type: application/json" \
        -d '{"question": "test"}' \
        http://localhost:3400/myFlow
  4. The request fails with an INVALID_ARGUMENT error because the handler receives undefined (since request.body.data is undefined).

Expected Behavior:

The official documentation for the Express.js integration should clearly specify the required request body structure. A curl example should be added to demonstrate the correct format:

# This is the correct, but undocumented, request format
curl -X POST -H "Content-Type: application/json" \
    -d '{"data": {"question": "test"}}' \
    http://localhost:3400/myFlow

Alternatively, the expressHandler could be updated to use request.body directly if request.body.data is undefined, which might be a more intuitive default behavior.

Conclusion:

Adding documentation and a clear example for this required "data" wrapper is essential for the usability of the Express.js integration. Without it, developers are likely to be blocked by a non-obvious API contract.

Environment:

  • @genkit-ai/express: v1.24.0
  • express: v4.21.1
  • Node.js version: v24.4.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsImprovements or additions to documentation

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions