Summary
Project.generate() works for the first screen in a project and then consistently throws StitchError: Incomplete API response from generate_screen_from_text: expected object at projection path on every subsequent screen in the same project. The underlying generate_screen_from_text MCP call succeeds and returns a complete screen; the SDK's hardcoded projection just lands in the wrong place.
Reproduce
SDK version: @google/stitch-sdk@0.1.0 (Node 22, Linux x64).
import { stitch } from "@google/stitch-sdk";
const project = await stitch.createProject("multi-screen-repro");
await project.generate("Home page"); // ✅ OK
await project.generate("Treatments page"); // ❌ throws StitchError
Root cause
packages/sdk/generated/src/project.ts hardcodes:
const _projected = raw?.outputComponents?.[1]?.design?.screens?.[0];
That index is correct for the first screen but not for subsequent screens in the same project. On call 1, Stitch returns a 6-component response that includes a designSystem prefix block at index 0, pushing the screen to index 1. On call 2+, the designSystem block is omitted (already established for the project), the response is one component shorter, and the screen sits at index 0.
Raw shape diff
Call 1 (fresh project, first screen) — 6 components:
outputComponents = [
{ designSystem: ... }, // index 0
{ design: { screens: [...] } }, // index 1 — SDK finds screen here
{ text: ... },
{ suggestion: ... },
{ suggestion: ... },
{ suggestion: ... }
]
Call 2 (same project, second screen) — 5 components:
outputComponents = [
{ design: { screens: [...] } }, // index 0 — SDK looks at index 1 and finds text instead
{ text: ... },
{ suggestion: ... },
{ suggestion: ... },
{ suggestion: ... }
]
Both responses contain a complete screen at <some index>.design.screens[0]; only the index varies.
Suggested fix
Scan outputComponents for the first entry whose .design.screens[0] is present, instead of hardcoding index 1:
let _projected;
for (const component of raw?.outputComponents ?? []) {
const screen0 = component?.design?.screens?.[0];
if (screen0) { _projected = screen0; break; }
}
Backwards-compatible with both the 6-component first-screen shape and the 5-component subsequent shape. Also forward-defensive against future shape drift — any additional prefix blocks that might get added won't break the lookup.
Workaround for consumers
Call generate_screen_from_text via callTool() directly and apply the scanning projection yourself. We've shipped this workaround in production for now.
Environment
@google/stitch-sdk 0.1.0
- Node.js 22
- Linux x64 (Railway worker runtime)
Happy to provide additional repro artefacts if useful — we have the full raw JSON for both call shapes saved.
Summary
Project.generate()works for the first screen in a project and then consistently throwsStitchError: Incomplete API response from generate_screen_from_text: expected object at projection pathon every subsequent screen in the same project. The underlyinggenerate_screen_from_textMCP call succeeds and returns a complete screen; the SDK's hardcoded projection just lands in the wrong place.Reproduce
SDK version:
@google/stitch-sdk@0.1.0(Node 22, Linux x64).Root cause
packages/sdk/generated/src/project.tshardcodes:That index is correct for the first screen but not for subsequent screens in the same project. On call 1, Stitch returns a 6-component response that includes a
designSystemprefix block at index 0, pushing the screen to index 1. On call 2+, thedesignSystemblock is omitted (already established for the project), the response is one component shorter, and the screen sits at index 0.Raw shape diff
Call 1 (fresh project, first screen) — 6 components:
Call 2 (same project, second screen) — 5 components:
Both responses contain a complete screen at
<some index>.design.screens[0]; only the index varies.Suggested fix
Scan
outputComponentsfor the first entry whose.design.screens[0]is present, instead of hardcoding index 1:Backwards-compatible with both the 6-component first-screen shape and the 5-component subsequent shape. Also forward-defensive against future shape drift — any additional prefix blocks that might get added won't break the lookup.
Workaround for consumers
Call
generate_screen_from_textviacallTool()directly and apply the scanning projection yourself. We've shipped this workaround in production for now.Environment
@google/stitch-sdk0.1.0Happy to provide additional repro artefacts if useful — we have the full raw JSON for both call shapes saved.