BabylonJS/Babylon.js · error
Unsupported stencil OpFail mode: ${opFail}.
Error message
Unsupported stencil OpFail mode: ${opFail}. What it means
getNativeStencilOpFail translates a Babylon.js stencil fail-op constant (Constants.KEEP, ZERO, REPLACE, INCR, DECR, INVERT, INCR_WRAP, DECR_WRAP) into the corresponding Babylon Native engine enum. If the opFail value passed to applyStencil is not one of these known constants, the switch hits default and throws. It is a guard against passing invalid or unsupported stencil state to the native backend.
Source
Thrown at packages/dev/core/src/Engines/Native/nativeHelpers.ts:253
switch (opFail) {
case Constants.KEEP:
return _native.Engine.STENCIL_OP_FAIL_S_KEEP;
case Constants.ZERO:
return _native.Engine.STENCIL_OP_FAIL_S_ZERO;
case Constants.REPLACE:
return _native.Engine.STENCIL_OP_FAIL_S_REPLACE;
case Constants.INCR:
return _native.Engine.STENCIL_OP_FAIL_S_INCR;
case Constants.DECR:
return _native.Engine.STENCIL_OP_FAIL_S_DECR;
case Constants.INVERT:
return _native.Engine.STENCIL_OP_FAIL_S_INVERT;
case Constants.INCR_WRAP:
return _native.Engine.STENCIL_OP_FAIL_S_INCRSAT;
case Constants.DECR_WRAP:
return _native.Engine.STENCIL_OP_FAIL_S_DECRSAT;
default:
throw new Error(`Unsupported stencil OpFail mode: ${opFail}.`);
}
}
export function getNativeStencilDepthFail(depthFail: number): number {
switch (depthFail) {
case Constants.KEEP:
return _native.Engine.STENCIL_OP_FAIL_Z_KEEP;
case Constants.ZERO:
return _native.Engine.STENCIL_OP_FAIL_Z_ZERO;
case Constants.REPLACE:
return _native.Engine.STENCIL_OP_FAIL_Z_REPLACE;
case Constants.INCR:
return _native.Engine.STENCIL_OP_FAIL_Z_INCR;
case Constants.DECR:
return _native.Engine.STENCIL_OP_FAIL_Z_DECR;
case Constants.INVERT:
return _native.Engine.STENCIL_OP_FAIL_Z_INVERT;
case Constants.INCR_WRAP:
View on GitHub (pinned to 0592b347b8)
Solutions
- Pass opFail from Constants (e.g. Constants.KEEP, Constants.INCR, Constants.DECR_WRAP) instead of a raw number.
- Log/validate opFail before calling applyStencil to confirm it is a defined Constants stencil op.
- If a needed op is genuinely missing, check Babylon.js version and update, or open an issue to add the native mapping.
Example fix
// before engine.applyStencil(true, 0x150, 0x150, 0x150); // raw GL enums // after engine.applyStencil(true, Constants.INCR_SAT, Constants.INCR_SAT, Constants.INCR_SAT);
Defensive patterns
Strategy: validation
Validate before calling
const OPS = [BABYLON.Constants.KEEP, BABYLON.Constants.ZERO, BABYLON.Constants.REPLACE, BABYLON.Constants.INCR, BABYLON.Constants.DECR, BABYLON.Constants.INVERT, BABYLON.Constants.INCR_WRAP, BABYLON.Constants.DECR_WRAP];
if (!OPS.includes(opFail)) throw new RangeError(`opFail must be a Constants stencil op, got ${opFail}`);
engine.applyStencil(face, opFail, depthFail, opPass); Type guard
function isStencilOp(v: unknown): v is number {
const C = BABYLON.Constants;
return typeof v === 'number' && [C.KEEP, C.ZERO, C.REPLACE, C.INCR, C.DECR, C.INVERT, C.INCR_WRAP, C.DECR_WRAP].includes(v);
} Try / catch
try {
engine.applyStencil(face, opFail, depthFail, opPass);
} catch (e) {
if (String(e.message).startsWith('Unsupported stencil OpFail')) {
console.warn('Bad opFail, falling back to KEEP', opFail);
engine.applyStencil(face, BABYLON.Constants.KEEP, depthFail, opPass);
} else throw e;
} Prevention
- Always pass Constants.* stencil enums, never raw WebGL GLenum numbers.
- Centralize stencil state setup in one helper that validates ops.
- Add a unit test asserting each applyStencil argument is a defined Constants value.
When it happens
Trigger: Calling engine.applyStencil(faceMode, opFail, ...) with an opFail value that is not one of the Constants stencil ops, e.g. a raw integer that doesn't match any case, undefined/null, or a value from a different API.
Common situations: Hand-rolling stencil state with magic numbers instead of Constants enums; porting WebGL code to Babylon Native where an op constant is out of range; a typo or stale constant from another Babylon version.
Related errors
- Unsupported stencil depthFail mode: ${depthFail}.
- Unsupported stencil opPass mode: ${opPass}.
- Unsupported alpha mode: ${mode}.
- Unsupported attribute type: ${type}.
- SHADER ERROR" + (typeof message === "string" ? "\n" + messag
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/8e8f80c26262454c.
Report an issue: GitHub.