You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CI type-check can fail with TS2306 ".source/server.ts is not a module": next typegen exits while fumadocs-mdx's un-awaited regeneration is still writing .source #311
Found by the repo:objectos seat on 2026-10-06, when the first main run after PR #310 went red. Priority: P1. A red build on main skips the deploy, so a landed change is not published.
[MDX] generated files in 63.02571499999999ms
Generating route types...
✓ Types generated successfully
lib/source.ts(1,22): error TS2306: File '/home/runner/work/objectos/objectos/apps/docs/.source/server.ts' is not a module.
The same tree passed:5d2f837 and the PR head 911a174 have the same tree, 263e370. The PR's run 37476364739 passed this step 14 minutes earlier.
The re-run passed: attempt 2 of the same run passed build.
The record: this is the first such failure in the last 40 CI runs.
Root cause (read from the installed source)
apps/docs runs "type-check": "fumadocs-mdx && next typegen && tsc --noEmit".
fumadocs-mdx (the CLI) writes .source/* and awaits the writes.
next typegen loads next.config.mjs, which calls createMDX(). In fumadocs-mdx 15.0.7, dist/next/index.js:14-20, createMDX() calls init(isDev, core)without awaiting it. init recompiles source.config.ts and calls core.emit({ write: true }), which rewrites every .source/* file with fs.writeFile (dist/core-DlDe_Eze.js:232-236). writeFile truncates the file first.
If next typegen finishes before that floating promise has written the file, the process exits with .source/server.ts truncated. tsc then reads an empty file, which is "not a module".
The two logs show the difference.
The passing PR run prints [MDX] generated files twice before ✓ Types generated successfully: once from the CLI, once from createMDX's write inside typegen.
The failing run prints it only once: typegen exited before its own regeneration finished.
Why it showed now: PR #310 made source.config.ts import rehypeCodeDefaultOptions from fumadocs-core/mdx-plugins, for the Shiki colorReplacements. That makes the config that init recompiles heavier to load, which plausibly widens the window. Before #310 the file imported only fumadocs-mdx/config, fumadocs-core/source/schema and node:path.
Done looks like
The step cannot end with a truncated .source. For example, reorder it to next typegen && fumadocs-mdx && tsc --noEmit, so the awaited CLI write is the last writer. Or use another fix that removes the race rather than shrinking it. State the choice, and check that next build, dev and postinstall are not exposed in the same way.
The race is reproduced red before the fix, for example by slowing init's write or by looping the step, and shown unable to occur after.
Repo gates are green, with the CI-shaped type-check and build.
No fumadocs-mdx patch, unless it is the only fix. An upstream report is welcome, from public facts only.
Found by the
repo:objectosseat on 2026-10-06, when the firstmainrun after PR #310 went red. Priority: P1. A redbuildonmainskips the deploy, so a landed change is not published.What happened
5d2f837, PR docs: contrast, phone table affordance, FAQ headings, title-weighted per-locale search, consistency pass (#301) #310's squash), attempt 1. Itsbuildjob failed atpnpm turbo run type-check:5d2f837and the PR head911a174have the same tree,263e370. The PR's run 37476364739 passed this step 14 minutes earlier.build.Root cause (read from the installed source)
apps/docsruns"type-check": "fumadocs-mdx && next typegen && tsc --noEmit".fumadocs-mdx(the CLI) writes.source/*and awaits the writes.next typegenloadsnext.config.mjs, which callscreateMDX(). In fumadocs-mdx 15.0.7,dist/next/index.js:14-20,createMDX()callsinit(isDev, core)without awaiting it.initrecompilessource.config.tsand callscore.emit({ write: true }), which rewrites every.source/*file withfs.writeFile(dist/core-DlDe_Eze.js:232-236).writeFiletruncates the file first.next typegenfinishes before that floating promise has written the file, the process exits with.source/server.tstruncated.tscthen reads an empty file, which is "not a module".The two logs show the difference.
[MDX] generated filestwice before✓ Types generated successfully: once from the CLI, once fromcreateMDX's write inside typegen.Why it showed now: PR #310 made
source.config.tsimportrehypeCodeDefaultOptionsfromfumadocs-core/mdx-plugins, for the ShikicolorReplacements. That makes the config thatinitrecompiles heavier to load, which plausibly widens the window. Before #310 the file imported onlyfumadocs-mdx/config,fumadocs-core/source/schemaandnode:path.Done looks like
.source. For example, reorder it tonext typegen && fumadocs-mdx && tsc --noEmit, so the awaited CLI write is the last writer. Or use another fix that removes the race rather than shrinking it. State the choice, and check thatnext build,devandpostinstallare not exposed in the same way.init's write or by looping the step, and shown unable to occur after.Generated by Claude Code