Skip to content

screen.edit() (and underlying edit_screens) returns success but never persists the change #361

Description

@RiddikZ

Summary

screen.edit() — and the edit_screens tool it wraps — accepts the request and returns a confident success (an agent message like "I've updated the heading to …" plus a precise dom_operations replace_content), but no new screen version is created and the change never renders. getHtml() after the edit returns the unchanged HTML. The same single-change edit applied in the Stitch web UI on the same screen works — so the bug is in the edit_screens write path, not in reads or in Stitch's edit capability.

Environment

  • @google/stitch-sdk (latest), Node + TS. Auth via STITCH_API_KEY.
  • Also reproduced via the raw Stitch MCP (stitch.googleapis.com/mcp, X-Goog-Api-Key) calling edit_screens directly.
  • All other operations work fine: generate, getHtml, getImage, list, create_project, design-system tools.

Repro (SDK)

import { stitch } from "@google/stitch-sdk"; // STITCH_API_KEY in env

const { result } = await stitch.callTool("create_project", { title: "edit-bug-repro" });
const projectId = result /* projects/<id> */ .split("/").pop();
const project = stitch.project(projectId);

const screen = await project.generate(
  'A minimal screen with one large centered heading that reads exactly "ORIGINAL HEADING ALPHA".',
);
const before = await fetch(await screen.getHtml()).then((r) => r.text());
// before contains "ORIGINAL HEADING ALPHA"  ✅

const edited = await screen.edit(
  'Change the heading text to read exactly "EDITWORKS BRAVO 9X". Change nothing else.',
);
// edited resolves OK; the agent reports success + dom_operations replace_content → "EDITWORKS BRAVO 9X"

const after = await fetch(await edited.getHtml()).then((r) => r.text());
// EXPECTED: after contains "EDITWORKS BRAVO 9X"
// ACTUAL:   after === before  → still "ORIGINAL HEADING ALPHA", byte-identical, same file id

Expected: after edit(), the screen's HTML reflects the requested change (a new version).

Actual: HTML is byte-identical to the pre-edit version; the screen's file id is unchanged even after a project refresh and several minutes. The change is silently not applied, despite the success response.

Discriminator (key)

Applying the identical edit through the Stitch web UI on the same screen — both a whole-screen prompt and an element-scoped prompt — does persist: a subsequent getHtml() immediately returns a new file id with the change. So reads are correct; only the programmatic edit_screens write path fails to persist.

Additional notes

  • Reproduced on existing, duplicated, and brand-new projects — identical result (not project-age related).
  • One edit_screens call once returned 401 "Expected OAuth 2 access token, login cookie or other valid authentication credential", though other calls (and every other tool) authenticate fine with the API key.

Impact

Any programmatic edit is a no-op. This also breaks the Edit flow of the official stitch-design/generate-design skill, which calls edit_screens.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions