stride3d/stride · error · InvalidOperationException
Shader {name} could not be loaded
Error message
Shader {name} could not be loaded What it means
In the same lazy factory of ShaderLoaderBase.LoadExternalBuffer, after the file is confirmed to exist, LoadExternalFileContent(name, out filename, out code, out h) is called to read and hash the shader source. A false return here (file exists but its content could not be read/decoded, or hashing failed) triggers "Shader {name} could not be loaded". This is the read-failure stage between existence checking and compilation.
Solutions
- Check file access permissions and that no other process holds a lock on the .sdsl file.
- Re-copy or restore the shader file in the output/source directory (may be truncated or corrupt).
- Retry after confirming the shader source directory is reachable (network drive mounted, virtual FS ready).
- If you implement a custom source provider, debug LoadExternalFileContent to see why it returns false for this name.
Example fix
// before (locked/corrupt file at shaders/MyShader.sdsl)
var buf = loader.LoadExternalBuffer("MyShader", macros, ...); // throws
// after: ensure the file is unlocked and present, or pre-check
if (!File.Exists(shaderPath) || !CanRead(shaderPath)) FixOrRestore(shaderPath);
var buf = loader.LoadExternalBuffer("MyShader", macros, ...); Defensive patterns
Strategy: retry
Validate before calling
var path = Path.Combine(shaderDir, name + ".sdsl"); if (!File.Exists(path)) throw new FileNotFoundException(path); using var fs = File.OpenRead(path); // throws earlier with a clearer error if locked
Try / catch
for (int attempt = 0; attempt < 3; attempt++)
{
try { loader.LoadExternalBuffer(name, macros, out var buf, out var h, out var c); break; }
catch (InvalidOperationException ex) when (ex.Message.Contains("could not be loaded") && attempt < 2)
{ Thread.Sleep(200); } // transient lock/AV scan
} Prevention
- Exclude shader directories from antivirus real-time scanning in build environments.
- Don't write shader files in-place while the game/effect compiler is reading them.
- Validate shader deployment (file sizes, counts) after build.
When it happens
Trigger: ExternalFileExists(name) returns true but LoadExternalFileContent fails: the file cannot be opened, an I/O error occurs, the file provider returns unreadable content, or content hashing fails for the shader source.
Common situations: File locked by another process or antivirus; permission issues on the shader directory; partially written/corrupt .sdsl file in the output folder; virtual file system or asset streaming glitch.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Shader {name} could not be found
- Shader {name} could not be compiled
- Invalid Shader stage specified in the Effect bytecode.
- Vulkan: bytecode is expected to be the same for all stages
- antialiasShaderName
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/34d80d17050f07ff.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs:70
isFromCache = false;
}
// 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)