pmndrs/react-three-fiber · error · Error

R3F: The args prop must be an array!

Error message

R3F: The args prop must be an array!

What it means

In R3F, the args prop is special: its array elements are spread into the THREE class constructor (e.g. new THREE.PerspectiveCamera(...args)). Because it must be spread, R3F requires args to be an array and validateInstance throws during createInstance/commitUpdate if any other value (object, string, number) is passed. This catches a common mistake before it becomes a cryptic constructor error.

Source

Thrown at packages/fiber/src/core/reconciler.tsx:187

  }
}

function validateInstance(type: string, props: HostConfig['props']): void {
  // Get target from catalogue
  const name = toPascalCase(type)
  const target = catalogue[name]

  // Validate element target
  if (type !== 'primitive' && !target)
    throw new Error(
      `R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`,
    )

  // Validate primitives
  if (type === 'primitive' && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`)

  // Throw if an object or literal was passed for args
  if (props.args !== undefined && !Array.isArray(props.args)) throw new Error('R3F: The args prop must be an array!')
}

function createInstance(type: string, props: HostConfig['props'], root: RootStore): HostConfig['instance'] {
  // Remove three* prefix from elements if native element not present
  type = toPascalCase(type) in catalogue ? type : type.replace(PREFIX_REGEX, '')

  validateInstance(type, props)

  // Regenerate the R3F instance for primitives to simulate a new object
  if (type === 'primitive' && props.object?.__r3f) delete props.object.__r3f

  return prepare(props.object, root, type, props)
}

function hideInstance(instance: HostConfig['instance']): void {
  if (!instance.isHidden) {
    if (instance.props.attach && instance.parent?.object) {
      detach(instance.parent, instance)

View on GitHub (pinned to ff3899dbf4)

Solutions

  1. Wrap the constructor arguments in an array: <perspectiveCamera args={[75, window.innerWidth / window.innerHeight, 0.1, 1000]} />.
  2. If you meant to set properties, not constructor arguments, move the value to a regular prop: <mesh frustumCulled={false} /> or use the pierce syntax like material-color="#ff0000".
  3. If args is dynamic, ensure the variable is an array before passing it, or default to undefined: <boxGeometry args={sizeArray ?? undefined} />.
  4. When changing args on an update, R3F re-instantiates the object, so keep the array stable-shaped (same length/kinds of args) to avoid remounting churn.

Example fix

// before
<perspectiveCamera args={75} /> // single value, not array
<boxGeometry args={{ width: 1, height: 1, depth: 1 }} /> // object, not array

// after
<perspectiveCamera args={[75, 1, 0.1, 1000]} />
<boxGeometry args={[1, 1, 1]} />
Defensive patterns

Strategy: type-guard

Validate before calling

const args = Array.isArray(size) ? size : [size]
<boxGeometry args={args} />

Type guard

const hasValidArgs = (props: { args?: unknown }): boolean =>
  props.args === undefined || Array.isArray(props.args)

Try / catch

null

Prevention

When it happens

Trigger: Passing args as an object (<mesh args={{width: 1}} />), a single value (<perspectiveCamera args={75} />), a string, or undefined-then-changed values during commitUpdate. Also triggered by typos where an options object was intended for a different prop but landed on args.

Common situations: Confusing args (constructor arguments array) with regular props (applied via .set()/assignment); copy-pasting THREE constructor signatures as an object; migrating code that passed a single constructor argument without wrapping it in an array; dynamic args built from a non-array variable.

Related errors


AI-assisted analysis of pmndrs/react-three-fiber@ff3899dbf4 (2026-08-28). Data as JSON: /api/errors/7ff06fc4f4aff13f. Report an issue: GitHub.