stride3d/stride · error · InvalidOperationException

Shader {name} could not be compiled

Error message

Shader {name} could not be compiled

What it means

Final stage of the lazy factory in ShaderLoaderBase.LoadExternalBuffer: the file exists and was read, but LoadFromCode(filename, code, h, macrosArray, out buf) returned false, meaning the SDSLC compilation pipeline did not produce a bytecode buffer. The loader throws "Shader {name} could not be compiled". In this overload no ILogger is attached, so the compiler's detailed errors were not rethrown and only this summary surfaces.

Solutions

  1. Attach a LoggerResult (set Log on the loader) so compile errors are captured and can be inspected instead of only getting the generic message.
  2. Fix the SSDL/SDSL compile errors reported in the logger output for that shader source.
  3. Test the shader with the failing macro combination in isolation to pinpoint which define breaks compilation.
  4. Check the compiler version matches what produced other shaders (feature drift).

Example fix

// before
var loader = new ShaderLoaderBase(...); // no Log -> only generic throw
// after
var log = new LoggerResult();
loader.Log = log;
try { loader.LoadExternalBuffer("MyShader", macros, out var buf, out var h, out var cached); }
catch (InvalidOperationException) { DumpErrors(log); }
Defensive patterns

Strategy: try-catch

Validate before calling

// no cheap pre-check exists; attach a logger and validate source separately
var log = new LoggerResult();
loader.Log = log;

Try / catch

try { loader.LoadExternalBuffer(name, macros, out var buf, out var h, out var cached); }
catch (InvalidOperationException ex) when (ex.Message.Contains("could not be compiled")) {
    foreach (var m in log.Messages.Where(m => m.Type >= LogMessageType.Error))
        Console.Error.WriteLine(m);
}

Prevention

When it happens

Trigger: Calling LoadExternalBuffer(name, defines, ...) where the .sdsl source has a compile error (syntax, unknown keyword, bad composition), or the compiler returned false for an internal reason, and no logger was set on the loader.

Common situations: SDSL syntax errors after editing a shader; incompatibility with macro combinations producing invalid code; shader using features the compiler version does not support.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/9a25f8801b5814a8. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs:73

        // Coordinate parallel compilations: only one thread compiles a given (name, macros) pair.
        var macrosHash = ComputeMacrosHash(defines);
        var macrosArray = defines.ToArray();
        var key = (name, macrosHash);

        var lazy = compilingShaders.GetOrAdd(key, _ => new Lazy<(ShaderBuffers, ObjectId)>(() =>
        {
            // Double-check cache (another thread may have finished between our check and this factory)
            if (Cache.TryLoadFromCache(name, null, macrosArray, out var buf, out var h) && ValidateCachedHashes(buf))
                return (buf, h);

            if (!ExternalFileExists(name))
                throw new InvalidOperationException($"Shader {name} could not be found");

            if (!LoadExternalFileContent(name, out var filename, out var code, out h))
                throw new InvalidOperationException($"Shader {name} could not be loaded");

            if (!LoadFromCode(filename, code, h, macrosArray, out buf))
                throw new InvalidOperationException($"Shader {name} could not be compiled");

            return (buf, h);
        }, LazyThreadSafetyMode.ExecutionAndPublication));

        try
        {
            var result = lazy.Value;
            buffer = result.Buffer;
            hash = result.Hash;
            isFromCache = false;
            return true;
        }
        finally
        {
            compilingShaders.TryRemove(key, out _);
        }
    }

View on GitHub (pinned to 96fad776d2)