stride3d/stride · error · InvalidOperationException
Shader could not be found
Error message
Shader {name} could not be found What it means
ShaderLoaderBase.LoadExternalBuffer resolves a shader by name through a lazy factory. After re-checking the cache, it calls ExternalFileExists(name); if the named shader file is not present anywhere the loader looks, it throws InvalidOperationException "Shader {name} could not be found". It is the loader's explicit 'shader not found' signal, distinct from 'found but failed to load/compile'.
Solutions
- Verify the shader name spelling matches the .sdsl file name exactly (case-sensitive on some platforms).
- Check the shader source directories/asset registry actually contain the .sdsl file and that ExternalFileExists would resolve it.
- Ensure the shader file is included in the project so it is copied to the output directory.
- Confirm the cache key/defines used are not aliasing a nonexistent combined shader name (name+macros).
Example fix
// before
var effect = new EffectCompiler().LoadExternalBuffer("MyShder", macros, ...); // typo
// after
var effect = new EffectCompiler().LoadExternalBuffer("MyShader", macros, ...); // matches MyShader.sdsl Defensive patterns
Strategy: validation
Validate before calling
if (!File.Exists(Path.Combine(shaderDir, name + ".sdsl")))
throw new FileNotFoundException($"Shader source missing: {name}.sdsl"); 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 found")) {
ReportMissingShader(name); // surface asset pipeline problem
} Prevention
- Keep shader names in constants/resources instead of raw strings to avoid typos.
- Verify .sdsl files are included in build output / asset dependencies.
- Run a pre-build validation that all referenced shaders resolve via ExternalFileExists.
When it happens
Trigger: Requesting a shader whose .sdsl file does not exist in any registered shader source directory; a typo in the shader name; requesting a shader that was never added to the shader source folders or SDSLC registry.
Common situations: Misspelled shader name in effect code; shader asset not copied to output / not in the asset dependency chain; differing shader directories between the editor and the compiled game.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Shader could not be loaded
- Shader could not be compiled
- Unable to find shader
- Package file [ ] was not found
- Cannot detect dependencies of projet
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/6ee73a168d6126ba.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs:67
if (ValidateCachedHashes(buffer))
return true;
// A dependency changed — invalidate and recompile
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;
}View on GitHub (pinned to 96fad776d2)