pixi-react icon indicating copy to clipboard operation
pixi-react copied to clipboard

Issue when running in strict mode.

Open timoch opened this issue 8 months ago • 11 comments

It seems like strict mode is making pixi react crash.

Scenario:

  • open page with pixi react setup and displaying correctly
  • navigate to previous page
  • navigate back to the page with pixi react setup
  • nothing is drawn on page
  • resize window
  • an error is logged.

The issue comes form a call to gl.getShaderSource() that returns null. At first glance it seems like pixi is somehow still referencing the previous gl context.

I'm using next.js. This happens when running in dev mode. If I build and test, it works fine.

logProgramError.mjs:7 Uncaught TypeError: Cannot read properties of null (reading 'split') at logPrettyShaderError (logProgramError.mjs:7:47) at logProgramError (logProgramError.mjs:33:7) at generateProgram (generateProgram.mjs:43:74) at GlShaderSystem._createProgramData (GlShaderSystem.mjs:113:111) at GlShaderSystem._getProgramData (GlShaderSystem.mjs:109:56) at GlShaderSystem._setProgram (GlShaderSystem.mjs:100:30) at GlShaderSystem.bind (GlShaderSystem.mjs:45:10) at GlBatchAdaptor.start (GlBatchAdaptor.mjs:31:21) at _BatcherPipe.execute (BatcherPipe.mjs:79:21) at executeInstructions (executeInstructions.mjs:11:40) at RenderGroupSystem.render (RenderGroupSystem.mjs:46:88) at SystemRunner.emit (SystemRunner.mjs:23:21) at WebGLRenderer.render (AbstractRenderer.mjs:103:25) at _Application.render (Application.mjs:38:19) at TickerListener.emit (TickerListener.mjs:44:18) at _Ticker.update (Ticker.mjs:263:29) at _tick (Ticker.mjs:72:14)

timoch avatar Apr 19 '25 11:04 timoch

I haven't been able to reproduce this in my own Next.js application. If you can provide a minimal reproduction of the bug, I'll be happy to take another look.

trezy avatar Apr 22 '25 11:04 trezy

I am seeing the same issue, only largely tied to Hot Module Reload, though admittedly, I am not using pixi-react.

I am using Pixi.js v8.9.1

My issue appears to be ultimately tied back to the use of Application.destroy. Removing this call addressed it on my side.

I am not confident on my usage of pixi to be able to advocate for it, but it does appear that we are using it in similar ways. I am going to leave mine off for now and circle back if I find memory leaks or similar.

https://github.com/pixijs/pixi-react/blob/a3e3128d63bbfa1e2caa1bb63eb2aa93f4d2d074/src/helpers/unmountRoot.ts#L18

Could be a fun project to tag team if you want to jump on discord and chase it down together.

BobGneu avatar Apr 23 '25 03:04 BobGneu

I've created as small reproduction. It behaves the same as on my project. But the actual error I get here is different. (That is if I get an error at all) I put 2 buttons on the main page that route the user to /canvas The first uses the router to push a new location. The other uses tag. The router button leads to a fail if you do button, browser back, button again The tag always works with that same scenario

Using the router, we can see the canvas blink into existence and then dissappear.

See code here : https://github.com/timoch/pixi-react-canvas-issue

I'm too new to either react or pixi to know where to begin investigating this...

timoch avatar Apr 23 '25 10:04 timoch

I can also confirm that when using strict mode.

createRoot(document.getElementById("app")!).render(
  <StrictMode>
    <App />
  </StrictMode>
);

...

const BunnySprite = () => {
  const { app } = useApplication();


...


  return (
    <pixiSprite
      x={app.screen.width}
      y={app.screen.height}
    />
  );
}

returns

TypeError: Cannot read properties of undefined (reading 'screen')

If I remove the strict mode wrapper, the error will be gone.

nicolasleander avatar Apr 27 '25 14:04 nicolasleander

I can also confirm that when using strict mode.

createRoot(document.getElementById("app")!).render(
  <StrictMode>
    <App />
  </StrictMode>
);

...

const BunnySprite = () => {
  const { app } = useApplication();


...


  return (
    <pixiSprite
      x={app.screen.width}
      y={app.screen.height}
    />
  );
}

returns

TypeError: Cannot read properties of undefined (reading 'screen')

If I remove the strict mode wrapper, the error will be gone.

Interesting, I have not experienced a case where I was ever able to access screen before the renderer was initialized, with or without StrictMode.

Application has an onInit function that allows you to wait for the renderer to be initialized if you need that functionaility.

export function App() {
  const [isInitialized, setIsInitialized] = useState(false);

  return (
    <Application onInit={() => setIsInitialized(true)}>
      <Stats />
      {isInitialized && < BunnySprite />}
    </Application>
  );
}

thejustinwalsh avatar May 02 '25 06:05 thejustinwalsh

There could be some unfortunate timing here with StrictMode... https://github.com/pixijs/pixi-react/blob/a3e3128d63bbfa1e2caa1bb63eb2aa93f4d2d074/src/helpers/queueForUnmount.ts#L11-L18

thejustinwalsh avatar May 02 '25 08:05 thejustinwalsh

Same here. Disabling StrictMode makes the error go away. We're on Next 15 w/ the latest pixi.js and pixi-react versions.

DiegoMonalee avatar May 28 '25 03:05 DiegoMonalee

Disabling StrictMode is not an option, is there any way to get around this some other way?

Ghostavio avatar Jun 11 '25 19:06 Ghostavio

Just came here to say it also affected me, seemingly out of nowhere. I made the page that used animations as the first thing in my website, but out of nowhere, without having touched it ever since, this error surfaced and returned a white canvas. I removed any logic besides the initial render (using default PIXI textures), and it still did not work. Disabling StrictMode in next.js settings worked.

I am using Next 15 and the latest pixi.js + pixi-react modules. My error appears on the first render, no resizing or actions required.

GabMacN avatar Jul 20 '25 20:07 GabMacN

I can confirm that this is still an issue. Canvas is in stale state when strict mode is enabled in Next 15. As long as the component is not rerendered the app works fine.

FunnyPaper avatar Sep 28 '25 18:09 FunnyPaper

I've been researching some issues on my side as well, with some crashes (not on strict mode), but I think they might be related

I'm getting:

Index range (first: 23976, count: 10, format: IndexFormat::Uint16) does not fit in index buffer size (36).
 - While encoding [RenderPassEncoder (unlabeled)].DrawIndexed(10, 1, 23976, 0, 0).
 - While finishing [CommandEncoder (unlabeled)].

and Cannot read properties of undefined (reading 'gpuProgram')

Based on this comment and my current reserach, it seems that when we navigate out of a page with a pixi application and back again very fast, we end up in a situation with two Pixi applications, when one is being destroyed. This probably be similar to the Strict mode, since it would re-render the application leading to these same issues.

According to this comment -- https://github.com/pixijs/pixijs/issues/11694#issuecomment-3334549087 -- It might be that we create a second application relying on the global resources of the first application that are being destroyed by the destroy().

This issue is intermitent and doesn't happen always, so it hints at some sort of race condition. Also it seems that the destroy is somehow messing also with the BatchPipe shader of webGPU. It might be that in the GL it first crashes on that generateProgram

The presented solution there is to use .destroy({ removeView: true, releaseGlobalResources: false }, true);, but that would leave dangling global resources. I wonder if there's any way to probe for other existing pixi applications running, and prevent destroy from removing the global resources.

sergioisidoro avatar Oct 17 '25 08:10 sergioisidoro