MonoGame/MonoGame · error · PipelineException

EffectMaterialContent.Effect or EffectMaterialContent.Compil

Error message

EffectMaterialContent.Effect or EffectMaterialContent.CompiledEffect should be set for materials with a custom effect.

What it means

Thrown by MaterialProcessor.Process when the input is an EffectMaterialContent with CompiledEffect set to null and Effect also set to null. An EffectMaterialContent represents a custom shader material, so at least one of Effect (source .fx reference) or CompiledEffect (pre-compiled effect reference) must be provided.

Source

Thrown at MonoGame.Framework.Content.Pipeline/Processors/MaterialProcessor.cs:173

                    newMaterial.Textures.Add(item.Key, item.Value);

                input = newMaterial;
            }

            // Docs say that if it's a basic effect, only build the diffuse texture.
            if (input is BasicMaterialContent basic)
            {
                if (basic.Textures.TryGetValue(BasicMaterialContent.TextureKey, out var texture))
                    basic.Texture = BuildTexture(texture.Filename, texture, context);

                return basic;
            }

            // Build custom effects
            if (input is EffectMaterialContent { CompiledEffect: null } effectMaterial)
            {
                if (effectMaterial.Effect == null)
                    throw new PipelineException("EffectMaterialContent.Effect or EffectMaterialContent.CompiledEffect should be set for materials with a custom effect.");
                effectMaterial.CompiledEffect = BuildEffect(effectMaterial.Effect, context);
                // TODO: Docs say to validate OpaqueData for SetValue/SetValueTranspose
                // Does that mean to match up with effect param names??
            }

            // Build all textures
            var keys = new List<string>(input.Textures.Keys);
            foreach (var key in keys)
            {
                var texture = input.Textures[key];
                var builtTexture = BuildTexture(texture.Filename, texture, context);
                input.Textures[key] = builtTexture;
            }

            return input;
        }

        /// <summary>

View on GitHub (pinned to 1d71bbd0ff)

Solutions

  1. Set effectMaterial.Effect to an ExternalReference<EffectContent> pointing to the .fx source file before processing.
  2. Alternatively set effectMaterial.CompiledEffect if you have a pre-compiled effect.
  3. If using an XML material definition, ensure it includes a valid <Effect> or <CompiledEffect> node.

Example fix

// before
var mat = new EffectMaterialContent();
// Effect and CompiledEffect both null
context.BuildAsset<MaterialContent, MaterialContent>(mat, ...);

// after
var mat = new EffectMaterialContent();
mat.Effect = new ExternalReference<EffectContent>("Effects/Custom.fx");
context.BuildAsset<MaterialContent, MaterialContent>(mat, ...);
Defensive patterns

Strategy: validation

Validate before calling

// Validate EffectMaterialContent before processing
if (input is EffectMaterialContent emc && emc.CompiledEffect == null && emc.Effect == null)
    throw new InvalidOperationException("EffectMaterialContent requires Effect or CompiledEffect to be set.");

Type guard

// Type guard for a valid effect material
static bool HasValidEffect(EffectMaterialContent emc) =>
    emc.Effect != null || emc.CompiledEffect != null;

Try / catch

try
{
    context.BuildAsset<MaterialContent, MaterialContent>(material, new MaterialProcessor());
}
catch (PipelineException ex) when (ex.Message.Contains("EffectMaterialContent"))
{
    context.Logger.LogImportantMessage("EffectMaterialContent needs Effect or CompiledEffect set.");
    throw;
}

Prevention

When it happens

Trigger: Creating an EffectMaterialContent programmatically or via .mgcontent XML without setting either the Effect or CompiledEffect property, then passing it through the MaterialProcessor pipeline.

Common situations: A material XML file declares a custom effect material but omits the <Effect> or <CompiledEffect> element. Programmatically constructing an EffectMaterialContent and forgetting to assign Effect before processing. Deserialization from a malformed or incomplete material definition.

Related errors


AI-assisted analysis of MonoGame/MonoGame@1d71bbd0ff (2026-08-13). Data as JSON: /api/errors/b885660549847bf2. Report an issue: GitHub.