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

  1. Read the `Available exports:` line in the error and either rename your export to `AppRouter` or pass `exportName: '<actualName>'`.
  2. Add `export type AppRouter = typeof yourRouter` to the file.
  3. 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

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


AI-assisted analysis of trpc/trpc@acff82332d (2026-08-12). Data as JSON: /api/errors/0887bdabc39120e8. Report an issue: GitHub.