moeru-ai/airi · warning

Failed to set colorSpace on texture:

Error message

Failed to set colorSpace on texture:

What it means

While normalizing MToon/NPR materials on the freshly loaded VRM, the component assigns SRGBColorSpace to each material's map texture inside a try/catch. If the texture's colorSpace setter throws (already-disposed texture, exotic texture subclass, engine edge case), the assignment is skipped with this warning and material setup continues — the model still renders, possibly with slightly wrong color gamma on that material.

Source

Thrown at packages/stage-ui-three/src/components/Model/VRMModel.vue:810

    /*
      * Shader setting
    */
    const isShaderMat = (m: any): m is ShaderMaterial => !!m?.isShaderMaterial

    function configureInjectedShaderMaterial(mat: ShaderMaterial) {
      if ('toneMapped' in mat)
        mat.toneMapped = false
      if ('envMap' in mat && mat.envMap)
        mat.envMap = null

      // NPR materials usually use sRGB textures.
      const tex = (mat as any).map as Texture | undefined
      if (tex && (tex as any).colorSpace !== undefined) {
        try {
          (tex as any).colorSpace = SRGBColorSpace
        }
        catch (e) {
          console.warn('Failed to set colorSpace on texture:', e)
        }
      }

      injectDiffuseIBL(mat)
    }

    // MToon material sky box lightProbe setting
    if (!airiIblProbe && scene.value)
      airiIblProbe = createIblProbeController(scene.value)

    // Material traverse setting
    _vrm.scene.traverse((child) => {
      if (child instanceof Mesh && child.material) {
        const material = Array.isArray(child.material) ? child.material : [child.material]
        material.forEach((mat, materialIndex) => {
          if (mat instanceof MeshStandardMaterial || mat instanceof MeshPhysicalMaterial) {
            // Should read envMap intensity from outside props
            mat.envMapIntensity = 1.0

View on GitHub (pinned to 677329427f)

Solutions

  1. Usually ignorable: rendering continues and only sRGB enforcement for that material is skipped
  2. Reproduce with a single, undisturbed model load — if the throw persists, inspect the texture instance type on the offending material
  3. Update three / @pixiv three-vrm packages in case Texture setter behavior changed
  4. If tied to one model, re-export the model and its textures with standard settings
Defensive patterns

Strategy: try-catch

Validate before calling

// Skip assignment when the texture is disposed or lacks the setter
const tex = (mat as any).map as Texture | undefined
if (tex && !('dispose' in tex && (tex as any).disposed) && (tex as any).colorSpace !== undefined) {
  ;(tex as any).colorSpace = SRGBColorSpace
}

Type guard

function isAssignableTexture(tex: unknown): tex is Texture {
  return tex instanceof Texture && !(tex as any).disposed
}

Try / catch

try {
  ;(tex as any).colorSpace = SRGBColorSpace
}
catch (e) {
  // Non-fatal: continue material setup; log the material name to identify the offender
  console.warn('Failed to set colorSpace on texture:', e, mat.name)
}

Prevention

When it happens

Trigger: mat.map is a Texture whose colorSpace assignment raises: a texture disposed during a concurrent load cancellation, or a custom/proxy texture implementation that validates assignments.

Common situations: Rapid model switching where an in-flight load is being torn down; third-party VRM variants with unusual material/texture implementations; three.js version changes altering Texture setter behavior.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/a4739d523db5022c. Report an issue: GitHub.