withastro/astro · critical · Error

The TypeScript module loaded${version} does not expose the p

Error message

The TypeScript module loaded${version} does not expose the programmatic API that `astro check` relies on. TypeScript's native compiler (7.0 and later) does not ship this API yet. Until it does, run `astro check` with a TypeScript version that still provides it (6.x). See https://github.com/withastro/roadmap/discussions/1321 to track support.

What it means

Thrown by the Astro language server's `assertCompatibleTypeScript()` when the loaded TypeScript module exposes only `version`/`versionMajorMinor` (the shape of TypeScript 7.x native compiler) but not the programmatic API (`ts.sys`, `ts.findConfigFile`) that `astro check` depends on via Volar. It fails early instead of crashing later with an opaque undefined-access error.

Source

Thrown at packages/language-tools/language-server/src/check.ts:209

						this.ts,
						languageServiceHost,
					);
				},
			);
		}
	}

	/**
	 * The checker is built on Volar and TypeScript's programmatic Language Service API
	 * (`ts.sys`, `ts.findConfigFile`, `LanguageServiceHost`, etc.). TypeScript's native
	 * compiler does not ship that API yet — `require('typescript')` only exposes `version`
	 * and `versionMajorMinor` — so continuing would crash later with an opaque
	 * `Cannot read properties of undefined` error. Fail early with an actionable message.
	 */
	private assertCompatibleTypeScript() {
		if (typeof this.ts.findConfigFile !== 'function' || this.ts.sys === undefined) {
			const version = this.ts.version ? ` (found ${this.ts.version})` : '';
			throw new Error(
				`The TypeScript module loaded${version} does not expose the programmatic API that \`astro check\` relies on. ` +
					`TypeScript's native compiler (7.0 and later) does not ship this API yet. ` +
					`Until it does, run \`astro check\` with a TypeScript version that still provides it (6.x). ` +
					`See https://github.com/withastro/roadmap/discussions/1321 to track support.`,
			);
		}
	}

	private getTsconfig() {
		if (this.tsconfigPath) {
			const tsconfig = resolve(this.workspacePath, this.tsconfigPath.replace(/^~/, homedir()));
			if (!existsSync(tsconfig)) {
				throw new Error(`Specified tsconfig file \`${tsconfig}\` does not exist.`);
			}
			return tsconfig;
		}

		const searchPath = this.workspacePath;

View on GitHub (pinned to d081033d5f)

Solutions

  1. Downgrade the project's TypeScript to 6.x: `pnpm add -D typescript@~6`.
  2. Ensure the `typescript.tsdk` init option points at a 6.x lib directory.
  3. Track the Astro roadmap discussion linked in the message for when TS 7 support lands.

Example fix

// before: typescript 7 resolved
pnpm add -D typescript@latest
// after
pnpm add -D typescript@~6
Defensive patterns

Strategy: type-guard

Validate before calling

import * as ts from 'typescript';
if (typeof ts.findConfigFile !== 'function' || ts.sys === undefined) {
  throw new Error('Incompatible TypeScript 7+; pin typescript@~6 for astro check.');
}

Type guard

function hasLanguageServiceAPI(ts: typeof import('typescript')): boolean {
  return typeof ts.findConfigFile === 'function' && ts.sys !== undefined;
}

Prevention

When it happens

Trigger: Running `astro check` in a project whose resolved `typescript` is 7.0+ (native compiler, no LanguageService API). Forcing `typescript.tsdk` to a TS 7 lib path. A toolchain (e.g. a newer bundler) hoisting TS 7 over TS 6.x.

Common situations: Upgrading TypeScript globally or in the project to 7.x. IDE/editor injecting a TS 7 lib. A fresh install resolving the latest TS major.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/682a8535aed204c7. Report an issue: GitHub.