Turborepo Cache Invalidation Failing for Markdown Content Changes
Problem
Turborepo cache invalidation was not working for content changes in the Astro monorepo. New markdown (.md) content files added to apps/sendy-hq/src/content/overnight/ were not appearing in deployed builds, displaying stale cached content instead.
The sendy-hq site showed only 1 overnight report after deploy, when ~10 new reports had been added.
Investigation
-
Symptom identification: After deploying new content to sendy-hq, only 1 overnight report appeared on the live site despite multiple new .md files being added locally.
-
File verification: Confirmed that all new .md content files existed in the repository at the correct location (
apps/sendy-hq/src/content/overnight/). -
Build pipeline analysis: Examined the GitHub Actions workflow which used
pnpm turbo build --filter='./apps/*[HEAD^1]'to detect and rebuild only changed applications using Turborepo’s change detection. -
Cache detection: Realized that Turbo’s default input configuration did not explicitly include markdown (.md) files in its cache invalidation hash calculation.
Root Cause
Turborepo’s default hashing mechanism for determining cache validity does not automatically include all file types in cache keys. When only .md content files changed without corresponding changes to .ts, .astro, or configuration files, Turbo’s computed hash remained identical to previous builds. This caused Turbo to serve the cached dist/ directory from a prior build instead of rebuilding with the new content.
Solution
Updated turbo.json to explicitly include all content files in the build task’s inputs:
"build": {
"dependsOn": ["^build"],
"inputs": ["src/**", "public/**", "*.ts", "*.mts", "*.json", "*.astro"],
"outputs": ["dist/**"]
}
The "src/**" glob pattern ensures that any file changes under the src/ directory — including markdown content files — trigger cache invalidation and force a rebuild.
Verification
After applying the fix to turbo.json, a deployment was forced via GitHub Actions workflow_dispatch trigger. The build process used the updated inputs configuration, which properly detected the content changes and rebuilt the affected applications. All overnight reports subsequently appeared correctly in the deployed site.
Prevention
- Document all content file types that trigger builds in
turbo.json. When Astro processes.mdfiles into static HTML, those changes must be explicitly listed in theinputsarray or cache misses occur silently. - Pre-deployment checklist: After adding new file types (
.md,.json,.yaml, templates), verify they’re inturbo.jsoninputsfor affected tasks before merging. - Test cache behavior locally before deploying:
pnpm turbo build --filter=<slug> --force(fresh) vs without--force(cached) should produce identical output.
What to Check When Adding New File Types
- Content files (
.md,.mdx,.yaml,.toml): Must be ininputsif read during build. - Config files (
.ts,.json,.mts): Check if the build task sources them. - Static assets (
public/**): Verifyinputsincludes them. - CI context: Test in GitHub Actions, not just locally. Turborepo’s cache directory behavior differs between local and CI runners.
Best Practices
- Explicit over implicit — List all meaningful patterns rather than relying on defaults.
- Separate build tasks by scope — Content-heavy sites (blogs, docs) may need different inputs than product sites.
- Include root configuration — Add
turbo.json,package.json, andtsconfig.jsontoinputsto invalidate cache when build tooling changes.
Debugging Checklist
- Verify task inputs in
turbo.jsoninclude all relevant file types - Force a fresh build:
pnpm turbo build --filter=<slug> --forceand compare output - Check for “cache hit” vs “cache miss” in verbose build logs
- Test content-only changes: modify only a
.mdfile and rebuild; cache should miss - Validate glob patterns against your file tree
- Inspect
.turbo/cache directory for stale entries - Check if
.gitignoreor.turbignorepatterns exclude source files - Review CI vs local — GitHub Actions may cache Turbo state across runs
Related
docs/solutions/build-errors/tailwind-v4-astro-integration.md— Another Astro build configuration issuedocs/solutions/build-errors/pnpm-monorepo-missing-dependency.md— pnpm strict dependency resolutiondocs/solutions/ci-issues/hallucinated-github-actions-sha-pins.md— CI pipeline issueturbo.json— Current Turborepo configuration.github/workflows/deploy.yml— GitHub Actions deploy workflow