gatsbyjs/gatsby · critical

The `id` parameter passed to createNodeId must be a String o

Error message

The `id` parameter passed to createNodeId must be a String or Number (got ${typeof id})

What it means

createNodeId generates deterministic UUIDs from an input id and a namespace. The id parameter must be a string or number (numbers are coerced to strings). If it is any other type (object, undefined, null, boolean, array), Gatsby panics because the UUID generation cannot produce a deterministic hash.

Source

Thrown at packages/gatsby/src/utils/create-node-id.ts:40

 * - The conversion needs to be fast
 * - The result should be predictably short as it may be used in urls
 *
 * High level this step is meant to prevent people from using our `id` to have meaning in their site and it's meant
 * to make sure the id ends up being short, whatever the input size was.
 *
 * Note: UUID is relatively slow because it calls into the native crypto library to generate SHA-1 hashes.
 *       We do need the low collision rate of SHA-1 so we use a local (global) cache to speed up repetitive calls
 *
 * @param {String | Number} id - A string of arbitrary length
 * @param {String} namespace - Namespace to use for UUID
 *
 * @return {String} - UUID
 */
export function createNodeId(id: string | number, namespace: string): string {
  if (typeof id === `number`) {
    id = id.toString()
  } else if (typeof id !== `string`) {
    report.panic(
      `The \`id\` parameter passed to createNodeId must be a String or Number (got ${typeof id})`
    )
  } else if (typeof namespace !== `string`) {
    report.panic(
      `The \`namespace\` parameter passed to createNodeId must be a String (got ${typeof namespace})`
    )
  }

  let nsHash = unprefixedCache.get(namespace)
  if (!nsHash) {
    nsHash = uuidv5(namespace, seedConstant) as string
    unprefixedCache.set(namespace, nsHash)
  }

  // Calling uuid is relatively expensive because it calls into crypto for sha1.
  // We use a local map to cache calls with the same ns+id pair, which helps a lot.
  let nsCache = namespacedCache.get(namespace)
  if (!nsCache) {

View on GitHub (pinned to 8b06340921)

Solutions

  1. Ensure the first argument to createNodeId is always a string or number -- check the data source for null/undefined keys.
  2. Add a guard: createNodeId(String(record.id || record.slug || fallback), 'namespace').
  3. Log the value before calling createNodeId to identify which record produces the bad id.
  4. Fix upstream data fetching to always provide a valid identifier.

Example fix

// before
const nodeId = createNodeId(data.maybeId, 'my-plugin')

// after
if (!data.id) {
  reporter.warn(`Record missing id: ${JSON.stringify(data)}`)
  return
}
const nodeId = createNodeId(data.id, 'my-plugin')
Defensive patterns

Strategy: validation

Validate before calling

// Validate id before calling createNodeId
function validateCreateNodeIdInput(id) {
  if (typeof id !== 'string' && typeof id !== 'number') {
    throw new Error('createNodeId requires string or number, got ' + typeof id)
  }
}

validateCreateNodeIdInput(record.id)

Type guard

// Type guard for valid createNodeId id parameter
function isValidNodeId(id) {
  return typeof id === 'string' || typeof id === 'number'
}

if (!isValidNodeId(record.id)) {
  reporter.warn('Skipping node: invalid id type ' + typeof record.id)
  return
}
var nodeId = createNodeId(record.id, 'my-plugin')

Prevention

When it happens

Trigger: Calling createNodeId(undefined, 'namespace') or createNodeId({ id: 1 }, 'namespace') -- passing a non-string/non-number first argument. Typically inside sourceNodes, onCreateNode, or a source plugin where the id comes from upstream data that is unexpectedly undefined or an object.

Common situations: A source plugin fetches data where a record's primary key is null or missing, and that field is passed to createNodeId. A gatsby-node.js bug where a variable used as id is undefined due to a typo or missing data path. Passing an object instead of object.id.

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/a1d8e6e3791eae35. Report an issue: GitHub.