stride3d/stride · error · InvalidOperationException

Could not read file content for

Error message

Could not read file content for {arg2.Path}

What it means

EffectGenerator.GenerateShaderKeysAndEffects throws InvalidOperationException when arg2.GetText() returns null, i.e. the shader source file (.sdfx) content could not be read. The generator needs the preprocessed text to parse and emit shader keys/effects.

Solutions

  1. Verify the .sdfx file exists and is readable at arg2.Path (check project include/copy settings).
  2. Re-run the Stride shader compiler/generator with a clean output to restore missing intermediates.
  3. Check file encoding — save the file as UTF-8 and re-add to the project.
  4. Confirm the file is properly included in the stride project so its content is embedded/accessible.
Defensive patterns

Strategy: validation

Validate before calling

if (!File.Exists(arg2.Path) || new FileInfo(arg2.Path).Length == 0)
    throw new FileNotFoundException($"Shader source missing or empty: {arg2.Path}");

Try / catch

try { GenerateShaderKeysAndEffects(arg1, arg2); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Could not read file content")) { log.LogError($"Unreadable shader source: {arg2.Path}"); throw; }

Prevention

When it happens

Trigger: Running the Stride shader effect generator over a .sdfx file whose text cannot be obtained — unreadable/corrupt file, wrong path, encoding issues.

Common situations: Broken build pipeline where the shader source wasn't copied/generated; path casing or mapping issues on case-sensitive file systems; file deleted or locked between enumeration and read.

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


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs:29

{
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        var shaderFiles =
            context
                .AdditionalTextsProvider
                .Where(x => Path.GetExtension(x.Path).ToLowerInvariant() is ".sdfx" or ".sdsl");

        context.RegisterSourceOutput(shaderFiles, GenerateShaderKeysAndEffects);
    }

    private void GenerateShaderKeysAndEffects(SourceProductionContext arg1, AdditionalText arg2)
    {
        var filename = GetSafeHintName(arg2.Path);
        var isSdfx = Path.GetExtension(arg2.Path).Equals(".sdfx", StringComparison.OrdinalIgnoreCase);

        try
        {
            var preprocessedText = MonoGamePreProcessor.Run(arg2.GetText()?.ToString() ?? throw new InvalidOperationException($"Could not read file content for {arg2.Path}"), arg2.Path);
            var parsed = SDSLParser.Parse(preprocessedText);
            if (parsed.Errors.Count > 0)
            {
                var sb = new StringBuilder();
                foreach (var error in parsed.Errors)
                    sb.AppendLine($"#error Parse error: {error}");
                arg1.AddSource(filename, sb.ToString());
                return;
            }
            else if (parsed.AST == null)
            {
                arg1.AddSource(filename, "#error No AST parsed");
                return;
            }

            // .sdfx files must declare 'effect', not 'shader' — catch the mistake here
            // instead of silently emitting unbuildable C#.
            if (isSdfx && parsed.AST is Parsing.ShaderFile sdfxFile && HasShaderClassDeclaration(sdfxFile))

View on GitHub (pinned to 96fad776d2)