sync: concurrent runs can read a truncated route_meta_data.json (JSON.parse error)
Maintainers usually reply within 1 day
@Nic-Polumeyv is already working on this.
Since Sep 26, 2026.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 76/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- javascript, node.js
- Domain
- build-system, tooling
Research direction
Read packages/kit/src/core/sync/write_types/index.js around the metadata read and write, then inspect the sync call path in sync.js and exports/vite/index.js. Reproduce with several parallel svelte-kit sync commands if useful. Done means concurrent syncs no longer expose truncated JSON while normal route metadata generation still works.
Written by the indexing model from the issue text.
Description
👋 Claude (Fable 5.1) here, filing on behalf of @hibukki.
Describe the bug
sync reads and rewrites .svelte-kit/types/route_meta_data.json non-atomically (write_types/index.js:60-62 read, :132 writeFileSync). With two syncs running concurrently, one can read the file while the other has it truncated → JSON.parse('') throws. The comment above the read says concurrent invocations are expected.
Concurrent syncs are easy to hit: the plugin's config hook runs sync.all on every Vite config resolution, so e.g. vitest and svelte-kit sync && svelte-check running in parallel race.
Reproduction
Run several svelte-kit sync in parallel, repeatedly. The window is tiny (between writeFileSync's truncate and its write), so it's a rare flake rather than a reliable repro: seen once in ~50 runs.
Logs
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at write_all_types (node_modules/@sveltejs/kit/src/core/sync/write_types/index.js:62:51)
at create (node_modules/@sveltejs/kit/src/core/sync/sync.js:39:2)
at ... (node_modules/@sveltejs/kit/src/exports/vite/index.js:449:28)
System Info
macOS 26.6.2, Node 24.16.0, @sveltejs/kit 2.70.3 (same code on main)
Severity
annoyance
Proposed fix
Write via a per-process tmp file + renameSync, so a reader never sees a truncated/partial file (a shared tmp name would tear the same way). No test: a truncate-window race isn't deterministically testable. Happy to open a PR if you'd like one.
- fs.writeFileSync(meta_data_file, JSON.stringify(meta_data, null, '\t'));
+ // tmp + rename: another sync may be reading the file right now
+ const tmp_file = `${meta_data_file}.${process.pid}.tmp`;
+ fs.writeFileSync(tmp_file, JSON.stringify(meta_data, null, '\t'));
+ fs.renameSync(tmp_file, meta_data_file);
- Dominant language
- JavaScript
- Stars
- 20.9k
- Forks
- 2.4k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 83
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from sveltejs/kit
-
awaiting submitter
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
adapter-cloudflare: `cloudflare:workers` keeps using the old platform proxy after the Wrangler config reloads in devPossibly taken @svelte-triage-bot claimed this 3 days ago. Openpkg:adapter-cloudflare
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
svelte-package watch mode leaves the compiled .js of a deleted .ts file in the outputPossibly taken @svelte-triage-bot claimed this 5 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
types / typescript
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Maintainers usually reply within 1 day
-
Prerendering no longer shows progressMay be free again A pull request for this issue was closed without being merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
sveltejs/kit#17163 · 4 comments ·
Maintainers usually reply within 1 day
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
Maintainers usually reply within 1 day
-
bug needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
apex-dev-tools/apex-log-parser#199 ·
Maintainers usually reply within 1 day
-
Filter todos by all / active / completedPossibly taken A pull request linked to this issue is open or already merged. Openenhancement good first issue hacktoberfest help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
ReadBufferStream.addBuffer adds the full ArrayBuffer of a typed array view, and ignores its byteOffsetPossibly taken @wayfarer3130 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Expo 57 example: pnpm install fails with ERR_PNPM_TRUST_DOWNGRADEPossibly taken @github-actions claimed this today. Openbug react-native team/client-libraries
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
PostHog/posthog-js#5442 · 1 comment ·
Maintainers usually reply within 1 day