stride3d/stride · error · InvalidOperationException
compilationContext should inherit from ICompilationContext
Error message
compilationContext should inherit from ICompilationContext
What it means
The AssetDependenciesCompiler constructor takes the Type of the compilation context to use and validates that it implements ICompilationContext, throwing InvalidOperationException otherwise. Note the check message says "should inherit from" but the actual condition is assignability to the ICompilationContext interface.
Solutions
- Pass a concrete type implementing ICompilationContext, e.g. typeof(AssetCompilerContext).
- Swap the argument if you accidentally passed the compiler type instead of the context type.
- Verify with typeof(ICompilationContext).IsAssignableFrom(candidateType) before constructing.
- Update the type reference if the context class was refactored/renamed and lost its interface.
Example fix
// before var depsCompiler = new AssetDependenciesCompiler(typeof(MyAssetCompiler)); // compiler, not a context // after var depsCompiler = new AssetDependenciesCompiler(typeof(MyAssetCompilerContext)); // implements ICompilationContext
Defensive patterns
Strategy: validation
Validate before calling
if (!typeof(ICompilationContext).IsAssignableFrom(contextType))
throw new ArgumentException("Type must implement ICompilationContext", nameof(contextType));
var deps = new AssetDependenciesCompiler(contextType); Type guard
static bool IsCompilationContext(Type t) => t != null && typeof(ICompilationContext).IsAssignableFrom(t);
Try / catch
try
{
var deps = new AssetDependenciesCompiler(contextType);
}
catch (InvalidOperationException ex)
{
logger.Error($"{contextType} is not an ICompilationContext: {ex.Message}");
} Prevention
- Pass typeof(YourContext) where YourContext : ICompilationContext, not the compiler type.
- Add a startup smoke test that constructs AssetDependenciesCompiler with your context type.
- Keep context classes implementing ICompilationContext after refactors.
When it happens
Trigger: Constructing new AssetDependenciesCompiler(typeof(SomeCompilerBase)) with a type that does not implement ICompilationContext — e.g. passing an AssetCompiler, an Asset type, or an abstract context base class that only indirectly relates to compilation contexts.
Common situations: Mixing up AssetCompilerRegistry's compiler type with the compilation context type when wiring the dependency compiler; renaming/refactoring context classes so the referenced type no longer implements ICompilationContext; reflection-resolved type string pointing at the wrong class.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Type [ ] must be assignable to Asset
- Invalid required type
- Unexpected arguments
- This tool requires a build path.
- Type [ ] must be assignable to Asset or be a Package
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/268753586437098e.
Report an issue: GitHub.
Appendix: source
Thrown at sources/assets/Stride.Core.Assets/Compiler/AssetDependenciesCompiler.cs:26
namespace Stride.Core.Assets.Compiler;
/// <summary>
/// An asset compiler that will compile an asset with all its dependencies.
/// </summary>
public class AssetDependenciesCompiler
{
public readonly BuildDependencyManager BuildDependencyManager;
/// <summary>
/// Raised when a single asset has been compiled.
/// </summary>
public event EventHandler<AssetCompiledArgs>? AssetCompiled;
public AssetDependenciesCompiler(Type compilationContext)
{
if (!typeof(ICompilationContext).IsAssignableFrom(compilationContext))
throw new InvalidOperationException($"{nameof(compilationContext)} should inherit from ICompilationContext");
BuildDependencyManager = new BuildDependencyManager();
}
/// <summary>
/// Prepare the list of assets to be built, building all the steps and linking them properly
/// </summary>
/// <param name="context">The AssetCompilerContext</param>
/// <param name="assetItems">The assets to prepare for build</param>
/// <returns></returns>
public AssetCompilerResult PrepareMany(AssetCompilerContext context, List<AssetItem> assetItems)
{
var finalResult = new AssetCompilerResult();
var compiledItems = new Dictionary<AssetId, BuildStep>();
foreach (var assetItem in assetItems)
{
var visitedItems = new HashSet<BuildAssetNode>();
Prepare(finalResult, context, assetItem, context.CompilationContext, visitedItems, compiledItems);View on GitHub (pinned to 96fad776d2)