gatsbyjs/gatsby · error · Error

Plugins creating nodes can not set data on the reserved fiel

Error message

Plugins creating nodes can not set data on the reserved field "fields"
as this is reserved for plugins which wish to extend your nodes.

If your plugin didn't add "fields" you're probably seeing this
error because you're reusing an old node object.

Node:

${JSON.stringify(node, null, 4)}

Plugin that created the node:

${JSON.stringify(plugin, null, 4)}

What it means

Gatsby reserves the node.fields object for extensions added via the createNodeField action; source plugins must not populate it directly when calling createNode. The reducer/action layer checks `if (node.fields)` on the incoming node and throws, because allowing a plugin to seed fields would bypass ownership tracking (node.internal.fieldOwners) that lets multiple plugins extend the same node without colliding. The message also flags the common cause: reusing a stale node object that already had fields attached.

Source

Thrown at packages/gatsby/src/redux/actions/public.js:754

        errorObj.filePath = possiblyCodeFrame.fileName
        errorObj.location = {
          start: {
            line: possiblyCodeFrame.line,
            column: possiblyCodeFrame.column,
          },
        }
      }

      report.error(errorObj)
      hasErroredBecauseOfNodeValidation.add(result.error.message)
    }

    return { type: `VALIDATION_ERROR`, error: true }
  }

  // Ensure node isn't directly setting fields.
  if (node.fields) {
    throw new Error(
      stripIndent`
      Plugins creating nodes can not set data on the reserved field "fields"
      as this is reserved for plugins which wish to extend your nodes.

      If your plugin didn't add "fields" you're probably seeing this
      error because you're reusing an old node object.

      Node:

      ${JSON.stringify(node, null, 4)}

      Plugin that created the node:

      ${JSON.stringify(plugin, null, 4)}
    `
    )
  }

View on GitHub (pinned to 8b06340921)

Solutions

  1. Remove the `fields` key from the object passed to createNode: `const { fields, ...nodeToCreate } = node`.
  2. Use createNodeField({ node, name, value }) after createNode to attach derived/extension data.
  3. Build the node from scratch (only internal + top-level data fields) rather than reusing a node that already went through the pipeline.
  4. If you only need to update extension data on an existing node, do not call createNode again - use createNodeField.

Example fix

// before
const existing = getNode(id)
createNode({ ...existing, myNewData: 123 }) // existing.fields leaks in
// after
const { fields, ...base } = existing
createNode({ ...base, myNewData: 123 })
createNodeField({ node: getNode(id), name: `myNewData`, value: 123 })
Defensive patterns

Strategy: validation

Validate before calling

// Strip reserved keys before createNode.
function sanitizeNodeForCreate(node) {
  const { fields, ...rest } = node
  return rest
}
// usage: createNode(sanitizeNodeForCreate(raw))

Type guard

function isCreateSafeNode(node) {
  return node && typeof node === 'object' && !('fields' in node) &&
    node.internal && typeof node.internal.type === 'string'
}

Prevention

When it happens

Trigger: Calling actions.createNode({ ..., fields: { ... } }) with a node object whose top-level `fields` property is truthy. Typically happens when an object retrieved via getNode() (which already has fields from a prior createNodeField call) is mutated and passed back into createNode.

Common situations: Copying/pasting source-plugin code and forgetting to strip fields; fetching an existing node, augmenting it, and re-creating it; transforming a node and passing the whole original (with its fields) into createNode for the derived type.

Related errors


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