phaserjs/phaser · error · Error

Must set explicit renderType in custom environment

Error message

Must set explicit renderType in custom environment

What it means

Phaser's renderer auto-detection (AUTO -> WebGL or Canvas) relies on probing the host environment at runtime. When you opt out of that probing by setting `customEnvironment: true` or by passing your own `canvas`, Phaser refuses to guess a renderer and demands an explicit `renderType`. The check lives in CreateRenderer.js:34 and fires only when `renderType === CONST.AUTO` is combined with a custom environment/own canvas.

Source

Thrown at src/core/CreateRenderer.js:36

 * any canvas CSS styles and pixel art interpolation settings, then instantiates and assigns the renderer
 * to `game.renderer`.
 *
 * Relies upon two webpack global flags, `WEBGL_RENDERER` and `CANVAS_RENDERER`, which are defined at
 * build time and inlined into the bundle as compile-time constants. They are not available as runtime
 * variables and determine which renderer classes are included in the build.
 *
 * @function Phaser.Core.CreateRenderer
 * @since 3.0.0
 *
 * @param {Phaser.Game} game - The Phaser.Game instance on which the renderer will be set.
 */
var CreateRenderer = function (game)
{
    var config = game.config;

    if ((config.customEnvironment || config.canvas) && config.renderType === CONST.AUTO)
    {
        throw new Error('Must set explicit renderType in custom environment');
    }

    //  Not a custom environment, didn't provide their own canvas and not headless, so determine the renderer:
    if (!config.customEnvironment && !config.canvas && config.renderType !== CONST.HEADLESS)
    {
        if (config.renderType === CONST.AUTO)
        {
            config.renderType = Features.webGL ? CONST.WEBGL : CONST.CANVAS;
        }

        if (config.renderType === CONST.WEBGL)
        {
            if (!Features.webGL) { throw new Error('Cannot create WebGL context, aborting.'); }
        }
        else if (config.renderType === CONST.CANVAS)
        {
            if (!Features.canvas) { throw new Error('Cannot create Canvas context, aborting.'); }
        }

View on GitHub (pinned to 41be1e462b)

Solutions

  1. Set an explicit renderer type in the game config, e.g. `type: Phaser.WEBGL` (or `Phaser.CANVAS`, or `Phaser.HEADLESS` for non-visual servers).
  2. If you genuinely want auto-detection, remove `customEnvironment: true` and do not pass your own `canvas` — let Phaser create one.
  3. For headless servers/tests use `type: Phaser.HEADLESS` so no context creation is attempted.

Example fix

// before
new Phaser.Game({ customEnvironment: true, width: 800, height: 600 })
// after
new Phaser.Game({ customEnvironment: true, type: Phaser.CANVAS, width: 800, height: 600 })
Defensive patterns

Strategy: validation

Validate before calling

const cfg = { customEnvironment: true, /* ... */ }
const AUTO = Phaser.AUTO // numeric constant
if ((cfg.customEnvironment || cfg.canvas) && cfg.type === AUTO) {
  throw new Error('Config error: set an explicit type (Phaser.WEBGL/CANVAS/HEADLESS) when using customEnvironment/canvas')
}
const game = new Phaser.Game(cfg)

Prevention

When it happens

Trigger: Passing `new Phaser.Game({ customEnvironment: true })` (or `canvas: myCanvas`) while leaving the default `type: Phaser.AUTO` (the value of `Phaser.AUTO`). AUTO is numeric 1; the guard triggers on the AUTO branch regardless of host capabilities.

Common situations: Running Phaser in Electron/offscreen, NW.js, jsdom/headless test harnesses (Jest, Mocha), or server-side render farms where feature detection is unreliable or unwanted. Developers copy a minimal config and forget to pin the renderer.

Related errors


AI-assisted analysis of phaserjs/phaser@41be1e462b (2026-08-13). Data as JSON: /api/errors/3ffb233f88e2858b. Report an issue: GitHub.