Pothos
Guide

Troubleshooting

Start with the section that matches the error. If the issue persists, include the error message, package versions, and a minimal reproduction when reporting it.

Type issues

  1. Ensure that TypeScript is using strict mode

  2. Move your builder types to a separate named interface

    • This will make many type errors significantly more readable
import SchemaBuilder from '@pothos/core';

interface PothosTypes {
  Context: {
    user: {
      id: string;
    };
  };
}

const builder = new SchemaBuilder<PothosTypes>({});

Slow VS Code or TypeScript performance

  1. Ensure you are not including any very complex objects in your Context type. See https://github.com/microsoft/TypeScript/issues/45405

Runtime issues

Plugin methods are not defined

Check that the plugin is imported and configured as its documentation describes. Pothos plugins extend classes imported from @pothos/core; the application and plugin must resolve the same core instance. Duplicate installations or incompatible package versions can leave methods on a different copy of the class.

Inspect the dependency tree with your package manager:

npm ls @pothos/core
# or
pnpm why @pothos/core

Align the package versions and dependency resolution if they load different copies. The packages do not have to live in a particular root node_modules directory.

Received multiple implementations for plugin

By default, Pothos doesn't allow multiple plugin registrations with the same name. During development, it can be helpful to disable this check by setting SchemaBuilder.allowPluginReRegistration = true.

Keep in mind that this not only allows plugins to be updated when for example, using HMR but can also lead to unexpected behavior with plugins using the same name.

Refs are undefined

If refs are undefined, a circular import may be reading them before initialization. Check these boundaries:

  1. The builder is defined in a file that does not import any files that use the builder (or indirectly import it).
  2. builder.toSchema() is called in a file that is not imported by any files that use the builder.

This is generally done by having a simple builder.ts that initializes the builder to export. This file can also define some core parts of your schema (the query object, scalars etc). The rest of the schema can then import the builder from builder.ts. A schema.ts file can then import all files that define parts of the schema. schema.ts can then call builder.toSchema() and export the result for use by the server.

These boundaries let deferred field callbacks read initialized refs. Options evaluated immediately can still fail in an import cycle. See Circular References for the distinction between module initialization errors and recursive TypeScript inference, and App Layout for an example of these modules.

On this page