Skip to content

saving body-only edit deletes index.json without re-adding it (entryLayout: 'content' + format: {data:'json'}) #1617

Description

@DuvNguyen

Description

When saving an entry that uses entryLayout: 'content' with format: { data: 'json' }
(metadata in index.json, body in a separate content.mdoc/markdown file), editing
only the body content sometimes causes Keystatic to emit a Git commit that
deletes index.json without re-adding it, even though the metadata itself was
unchanged. Content.mdoc updates correctly; index.json is just gone.

Environment

  • @keystatic/core: 0.6.9
  • @keystatic/astro: 6.0.0
  • Storage: kind: 'github'
  • Collection: path: 'src/content/blog/*/', entryLayout: 'content', format: { data: 'json' }

Reproduction

  1. Open an existing entry in the GitHub-storage-mode admin UI.
  2. Edit only the markdoc body field (leave title/metadata untouched).
  3. Click Save.
  4. Inspect the resulting commit: index.json is deleted, content.mdoc is
    modified in place — no addition recreates index.json.

Evidence

Commit example (repo private, redacted path):
content.mdoc | 2 ++
index.json | 24 ----------------------
2 files changed, 2 insertions(+), 24 deletions(-)
delete mode 100644 .../index.json

A follow-up save then fails with:
[GraphQL] A path was requested for deletion which does not exist as of commit oid ''
because index.json was already deleted by the prior save.

Suspected root cause

In useUpsertItem (keystatic-core-ui.js), filesToDelete is derived from
args.initialFiles (a snapshot captured when the entry form was loaded) and
additions is filtered by comparing blob sha against unscopedTree
(a client-side cached tree). If that cached tree is stale relative to the
actual GitHub HEAD (e.g. after a previous save, or a tab left open), an
unchanged file can end up filtered out of additions while still remaining
in filesToDelete, producing a commit with a deletion but no matching
re-addition.

Related

Same symptom as #1269, which was closed without a root cause. This report
includes a concrete reproducible commit diff.

Impact

Data loss — entries silently disappear from the CMS (Entry not found,
0 entries) until manually restored from git history.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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