schema.getTypeNames is not a function error in Sanity Studio

21 replies
Last updated: Mar 14, 2022
Howdy everyone! When going through the Live Preview with Next.js and Sanity.io: A Complete Guide I am getting an unhandled error in the browser at 3333 despite a successful build. What’s odd is that this was working until reaching the section Setting up the Production Preview . Devtools:
Failed to load defined templates, falling back to defaults:
Console:
TypeError: schema.getTypeNames is not a function
    at Object.defaults (/static/js/app.bundle.js:103002:17)
    at getDefaultTemplates (/static/js/app.bundle.js:179904:44)
    at getTemplates (/static/js/app.bundle.js:179926:12)
    at Object.defaultInitialValueTemplateItems (/static/js/app.bundle.js:108729:59)
    at getNewDocumentOptions (/static/js/app.bundle.js:208056:93)
    at /static/js/app.bundle.js:208028:14
    at Object. (/static/js/app.bundle.js:289588:62)
    at __webpack_require__ (/static/js/vendor.bundle.js:713:30)
    at fn (/static/js/vendor.bundle.js:118:20)
    at Object. (/static/js/app.bundle.js:289528:29)
My schema is identical to the example. The /web front end builds perfectly, correctly pulling content from Sanity. There are no ESLint errors thanks to the
"eslint.workingDirectories": ["./web", "./studio"]
in
/.vscode/settings.json
and node_modules has been replaced already. Any ideas how I can track this down?
AI Update

I found the exact issue you're experiencing! This is a common problem when setting up the production preview feature in Sanity Studio v2 (the older version using sanity.json).

The error schema.getTypeNames is not a function happens because your sanity.json file has incorrectly combined two separate "parts" into one. Looking at your configuration:

"parts": [
  {
    "name": "part:@sanity/base/schema",
    "implements": "part:@sanity/production-preview/resolve-production-url",
    "path": "./resolve-production-url.js"
  }
]

The problem is that you're telling Sanity that your schema file is located at ./resolve-production-url.js, which is actually your production URL resolver. This causes the schema system to fail because it can't find the proper schema definition.

The Solution

You need to separate these into two distinct parts in your sanity.json:

"parts": [
  {
    "name": "part:@sanity/base/schema",
    "path": "./schemas/schema.js"
  },
  {
    "name": "part:@sanity/desk-tool/structure",
    "path": "./deskStructure.js"
  },
  {
    "implements": "part:@sanity/production-preview/resolve-production-url",
    "path": "./resolve-production-url.js"
  }
]

Key points:

  • The first entry should point to your actual schema file (wherever you have your createSchema export)
  • The production preview resolver uses "implements" instead of "name"
  • Each part needs its own separate object in the array

Make sure the path in the first entry ("./schemas/schema.js" or similar) matches where your actual schema file is located - the one with the createSchema function you shared earlier.

After making this change, restart your Studio dev server and the error should be resolved!

Note: If you're starting a new project today, I'd recommend using Sanity Studio v3, which has moved away from the sanity.json parts system to a more straightforward configuration approach using sanity.config.ts.

Show original thread
21 replies
// First, we must import the schema creator
import createSchema from 'part:@sanity/base/schema-creator';

// Then import schema types from any plugins that might expose them
import schemaTypes from 'all:part:@sanity/base/schema-type';

// Custom schemas
import page from './page';

// Then we give our schema to the builder and provide the result to Sanity
export default createSchema({
  // We name our schema
  name: 'default',
  // Then proceed to concatenate our document type
  // to the ones provided by any plugins that are installed
  types: schemaTypes.concat([page]),
});
Page schema is
export default {
  name: 'page',
  title: 'page',
  type: 'document',
  fields: [
    { name: 'title', type: 'string' },
    { name: 'slug', type: 'slug', options: { source: 'title' } },
    { name: 'content', type: 'text' },
  ],
};
That looks fine! Can you also share you
sanity.json
, your
resolveProductionUrl
and your
deskStructure
?
Sure
{
  "root": true,
  "project": {
    "name": "Gravyboat"
  },
  "api": {
    "projectId": "a0cf01go",
    "dataset": "production"
  },
  "plugins": [
    "@sanity/base",
    "@sanity/default-layout",
    "@sanity/default-login",
    "@sanity/desk-tool",
    "@sanity/production-preview"
  ],
  "env": {
    "development": {
      "plugins": ["@sanity/vision"]
    }
  },
  "parts": [
    {
      "name": "part:@sanity/base/schema",
      "implements": "part:@sanity/production-preview/resolve-production-url",
      "path": "./resolve-production-url.js"
    }
  ]
}
// ./studio/resolveProductionUrl.js

// Any random string, must match SANITY_PREVIEW_SECRET in the Next.js .env.local file
const previewSecret = '32o98jcawoniunf3q9048jsladknfgnhd09u4';

// Replace `remoteUrl` with your deployed Next.js site
const remoteUrl = `<https://gravyboat-dev.vercel.app/>`;
const localUrl = `<http://localhost:3000>`;

export default function resolveProductionUrl(doc) {
  const baseUrl = window.location.hostname === 'localhost' ? localUrl : remoteUrl;

  const previewUrl = new URL(baseUrl);

  previewUrl.pathname = `/api/preview`;
  previewUrl.searchParams.append(`secret`, previewSecret);
  previewUrl.searchParams.append(`slug`, doc?.slug?.current ?? `/`);

  return previewUrl.toString();
}
I do not have a deskStructure … would that be the issue?
Installing plugin and adding it now, BRB
user M
Failed to compile.

Error in ./node_modules/@sanity/base/lib/datastores/document/document-pair/validation.js
Module not found: Error: Can't resolve 'part:@sanity/base/schema' in '/Users/baller/Documents/GitHub/gravyboat-dev/studio/node_modules/@sanity/base/lib/datastores/document/document-pair'
New sanity.js looks like this now…
{
  "root": true,
  "project": {
    "name": "Gravyboat"
  },
  "api": {
    "projectId": "a0cf01go",
    "dataset": "production"
  },
  "plugins": [
    "@sanity/base",
    "@sanity/default-layout",
    "@sanity/default-login",
    "@sanity/desk-tool",
    "@sanity/production-preview",
    "iframe-pane"
  ],
  "env": {
    "development": {
      "plugins": [
        "@sanity/vision"
      ]
    }
  },
  "parts": [
    {
      "name": "part:@sanity/base/schema",
      "implements": "part:@sanity/production-preview/resolve-production-url",
      "path": "./resolve-production-url.js"
    },
    {
      "name": "part:@sanity/desk-tool/structure",
      "path": "./deskStructure.js"
    }
  ]
}
Would it be easier/faster if I share a repo with you
user M
?
Got it! The issue is with your parts in your
sanity.json
. You've combined your parts for resolving your production url and your schema. They need to be two distinct parts, fpr example:
"parts": [
    {
      "name": "part:@sanity/base/schema",
      "path": "./schemas/schema"
    },
    {
      "name": "part:@sanity/desk-tool/structure",
      "path": "./src/desk/deskStructure.js"
    },
    {
      "implements": "part:@sanity/production-preview/resolve-production-url",
      "path": "./src/resolveProductionUrl.js"
    },
  ]
Got it! The issue is with your parts in your
sanity.json
. You've combined your parts for resolving your production url and your schema. They need to be two distinct parts:
"parts": [
    {
      "name": "part:@sanity/base/schema",
      "path": "./schemas/schema"
    },
    {
      "name": "part:@sanity/desk-tool/structure",
      "path": "./src/desk/deskStructure.js"
    },
    {
      "name": "part:@sanity/base/new-document-structure",
      "path": "./src/newDocumentStructure.js"
    },
    {
      "implements": "part:@sanity/base/document-actions/resolver",
      "path": "./src/resolveDocumentActions.js"
    },
    {
      "implements": "part:@sanity/form-builder/input/image/asset-sources",
      "path": "./src/assetSources.js"
    },
    {
      "implements": "part:@sanity/form-builder/input/file/asset-sources",
      "path": "./src/assetSources.js"
    },
    {
      "implements": "part:@sanity/production-preview/resolve-production-url",
      "path": "./src/resolveProductionUrl.js"
    },
    {
      "implements": "part:@sanity/base/theme/variables/override-style",
      "path": "./src/variableOverrides.css"
    }
  ]

Note that the paths to the files is different in mine. You'd need to replace it with whatever yours is.
Ah!
You’re amazing
user M
as is your entire team. I will be selling Sanity hard to begin the process of freeing the internet from the blight of Wordpress…
Haha, so happy to help, Neil!
That did it! Learning something new every day. Have an awesome week
user M
!
You too!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?