Skip to content

audit: stale .astro content-layer cache serves wrong statement data after schema changes — dev showed '—' for all wallet PnL while prod showed values #39

Description

@tkowalczyk

Evidence (reproduced locally 2026-06-12)

Astro's glob loader caches parsed entries in .astro/data-store.json keyed by file content digest only. A schema change with unchanged content files does not invalidate the cache, so getEntry()/getCollection() keep returning data parsed by the old schema.

Observed concretely on this machine: .astro/data-store.json (mtime Jun 3) held top_wallets items as {truncated_id, category}hypothetical_pnl_usd stripped, because the cached parse predated commit a379d8b which added that field to truncatedWallet (Zod strips undeclared keys). A fresh pnpm dev on Jun 12 happily reused it: every wallet on /statements/2026-05-31-weekly rendered Bucket/Share as , while production (built fresh in CI) showed <$25 / ~+$25 / ~+$175 etc. Deleting data-store.json and re-syncing fixed dev instantly (done — local cache is healed).

Why it matters beyond confusing dev sessions: package.json exposes deploy, deploy:dev, deploy:staging, deploy:production that build locally — a local deploy after a schema change can ship stale/wrong data to a live Worker. CI deploys are safe only because the checkout is fresh.

TDD plan / fix directions (pick smallest that closes the hole)

  1. Make local builds immune: change the build script to clear the content-layer store first — "build": "astro build --force" if supported by the installed Astro (check astro build --help; content-layer --force re-syncs), else "prebuild": "rm -rf .astro/data-store.json". Test: a scripts/-level test (same convention as wrangler-config.test.ts) asserting the build/deploy scripts include the invalidation step — guards against someone removing it.
  2. Optionally do the same for dev (slower startup vs correctness — document the tradeoff; minimum: add a troubleshooting note in CLAUDE.md "if content data looks stale: rm .astro/data-store.json").
  3. Consider an upstream Astro issue/check — schema-hash-aware invalidation is arguably an Astro bug; worth a quick search of withastro/astro issues before working around it forever.

Acceptance criteria

AC Test
pnpm build (and all deploy:* paths) never reuses a parse made by an older schema script-content test + manual repro: stale store + build → built worker contains current fields
Documented recovery for dev staleness CLAUDE.md note

Metadata

Metadata

Assignees

No one assigned

    Labels

    afkAgent-grabbable: implementable without further inputbugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions