🐛 EffectComposer throws "Cannot read properties of undefined (reading 'length')" error
Environment
Reactversion: 19.0.0Nextversion: 15.1.4threeversion: 0.172.0@react-three/fiberversion: 9.0.0-rc.2@react-three/dreiversion: 9.120.6nodeversion: v23.4.0npmversion: 10.9.2
Problem description:
When using the EffectComposer component from react-three/postprocessing, I'm encountering a "Cannot read properties of undefined (reading 'length')" error. This error occurs in the useLayoutEffect hook of the EffectComposer component. The current behavior is problematic because it prevents the EffectComposer from initializing properly and applying post-processing effects to the scene.
Actuall Behavior
The application throws the following error:
EffectComposer.tsx:141 Uncaught TypeError: Cannot read properties of undefined (reading 'length') at EffectComposer.useLayoutEffect (EffectComposer.tsx:141:40)
Steps to Reproduce
- Create a React Three Fiber scene
- Add an EffectComposer component to the scene
- Render the scene
Code Example
import React from 'react'
import { Canvas } from '@react-three/fiber'
import { EffectComposer } from '@react-three/postprocessing'
function Scene() {
return (
<Canvas>
<mesh>
<boxGeometry />
<meshStandardMaterial />
</mesh>
<EffectComposer>
{/* Your effects here */}
</EffectComposer>
</Canvas>
)
}
@Mojtaba-amirii duplicate: https://github.com/pmndrs/react-postprocessing/issues/301
@CodyJasonBennett I'm getting the same error but with React 18.2
<EffectComposer>
<DepthOfField
focusDistance={0}
focalLength={0.02}
bokehScale={3}
height={400}
/>
</EffectComposer>
It's highlighting on this loop in EffectComposer.tsx @line 140
if (groupInstance && composer) {
const children = groupInstance.children
// SourceMap says its here
for (let i = 0; i < children.length; i++) {
const child = children[i].object
if (child instanceof Effect) {
const effects: Effect[] = [child]
if (!isConvolution(child)) {
let next: unknown = null
while ((next = children[i + 1]?.object) instanceof Effect) {
if (isConvolution(next)) break
effects.push(next)
i++
}
}
const pass = new EffectPass(camera, ...effects)
passes.push(pass)
} else if (child instanceof Pass) {
passes.push(child)
}
}
for (const pass of passes) composer?.addPass(pass)
if (normalPass) normalPass.enabled = true
if (downSamplingPass) downSamplingPass.enabled = true
}
@DennisSmolek This bug report is closed due it's duplicate to #301 and I suggest you follow the issue there. Although the bug is solved in React 19 with EffectComposer comp from react-three/postprocessing.
@DennisSmolek This bug report is closed due it's duplicate to #301 and I suggest you follow the issue there. Although the bug is solved in React 19 with EffectComposer comp from react-three/postprocessing.
The issue there is solely about things with react 19.
Please note I am using react 18 and having the issue that is titled here, not anything related to react 19.
So this is the correct place for it, not the react 19 section.
While I do have an a solution that works with everything at the latest I still have to make this work with older versions of react/next
I have the same issue with newer versions of react-postprocessing. For now reverted to v2.16.5, seems to be working.
Still reproducible in "@react-three/postprocessing": "^3.0.4", downgrade it to 2.16.5 as @andrisberzkalns suggested makes it work.