trpc/trpc · error · Error
No export named '${exportName}' found in: ${resolvedPath}\nA
Error message
No export named '${exportName}' found in: ${resolvedPath}\nAvailable exports: ${available || '(none)'} What it means
With the module symbol in hand, the generator enumerates exports and looks for one named `exportName` (default `'AppRouter'`). If none matches, it throws and lists the available export names so you can correct either the file or the `exportName` option.
Source
Thrown at packages/openapi/src/generate.ts:1502
const program = ts.createProgram([resolvedPath], compilerOptions);
const checker = program.getTypeChecker();
const sourceFile = program.getSourceFile(resolvedPath);
if (!sourceFile) {
throw new Error(`Could not load TypeScript file: ${resolvedPath}`);
}
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
if (!moduleSymbol) {
throw new Error(`No module exports found in: ${resolvedPath}`);
}
const tsExports = checker.getExportsOfModule(moduleSymbol);
const routerSymbol = tsExports.find((sym) => sym.getName() === exportName);
if (!routerSymbol) {
const available = tsExports.map((e) => e.getName()).join(', ');
throw new Error(
`No export named '${exportName}' found in: ${resolvedPath}\n` +
`Available exports: ${available || '(none)'}`,
);
}
// Prefer the value declaration for value exports; fall back to the declared
// type for `export type AppRouter = …` aliases.
let routerType: ts.Type;
if (routerSymbol.valueDeclaration) {
routerType = checker.getTypeOfSymbolAtLocation(
routerSymbol,
routerSymbol.valueDeclaration,
);
} else {
routerType = checker.getDeclaredTypeOfSymbol(routerSymbol);
}
const schemaCtx: SchemaCtx = {View on GitHub (pinned to acff82332d)
Solutions
- Read the `Available exports:` line in the error and either rename your export to `AppRouter` or pass `exportName: '<actualName>'`.
- Add `export type AppRouter = typeof yourRouter` to the file.
- Verify spelling/casing of the exportName option.
Example fix
// before
// src/router.ts: export type Router = typeof appRouter;
generateOpenApiDocument('src/router.ts'); // default exportName 'AppRouter' missing
// after — option A
generateOpenApiDocument('src/router.ts', { exportName: 'Router' });
// after — option B
export type AppRouter = typeof appRouter; Defensive patterns
Strategy: validation
Validate before calling
const expected = opts.exportName ?? 'AppRouter';
// introspect via ts-morph or a regex for `export type ${expected} =`
if (!new RegExp(`export\\s+type\\s+${expected}\\b`).test(src)) {
throw new Error(`File does not export '${expected}'`);
} Try / catch
try {
await generateOpenApiDocument(resolvedPath, opts);
} catch (e) {
if (e instanceof Error && /No export named/.test(e.message)) {
// set opts.exportName to an available export from the message
}
throw e;
} Prevention
- Standardize on the `AppRouter` export name across the repo.
- Pass `exportName` explicitly when the file uses a different name.
When it happens
Trigger: The router is exported under a different name (e.g., `export type Router` instead of `AppRouter`), or `options.exportName` was set to a value that isn't exported.
Common situations: Non-standard router naming, multiple routers in one file, or a typo in the `exportName` option.
Related errors
- No module exports found in: ${resolvedPath}
- Could not load TypeScript file: ${resolvedPath}
- INTERNAL_SERVER_ERROR
- BAD_REQUEST
- You seem to have several error formatters
AI-assisted analysis of trpc/trpc@acff82332d (2026-08-12).
Data as JSON: /api/errors/0887bdabc39120e8.
Report an issue: GitHub.