spectreconsole/spectre.console · error · InvalidOperationException

Failed to read colors.json at {file.Path}

Error message

Failed to read colors.json at {file.Path}

What it means

Thrown inside the colors.json Roslyn incremental source generator when an AdditionalFiles entry ending in colors.json was matched but AdditionalText.GetText returned null, i.e. the file was itemized by MSBuild but its contents could not be read at generation time. It is an InvalidOperationException raised inside the generator pipeline, so it surfaces as a compile-time build error.

Source

Thrown at src/Spectre.Console.SourceGenerator/Colors/ColorGenerator.cs:28

/// </summary>
[Generator]
public class ColorGenerator : IIncrementalGenerator
{
    // UTF-8 without a BOM, matching the repository's source file convention
    // and keeping the checked-in generated files deterministic.
    private static readonly Encoding Utf8NoBom = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

    /// <inheritdoc />
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        // Find colors.json and parse it in the pipeline (for caching)
        // Step 1: Extract text (cached by string value equality)
        // Step 2: Parse to models (cached by EquatableArray value equality)
        var colors = context.AdditionalTextsProvider
            .Where(static file => file.Path.EndsWith("colors.json", StringComparison.OrdinalIgnoreCase))
            .Select(static (file, ct) =>
                file.GetText(ct)?.ToString()
                ?? throw new InvalidOperationException($"Failed to read colors.json at {file.Path}"))
            .Select(static (text, _) => ColorParser.ParseAll(text))
            .Collect();

        // Register source output - only emit, no parsing (parsing is cached above)
        context.RegisterSourceOutput(colors, static (spc, models) =>
        {
            if (models.IsEmpty)
            {
                return;
            }

            if (models.Length > 1)
            {
                spc.ReportDiagnostic(Diagnostic.Create(
                    new DiagnosticDescriptor(
                        "SPECINTERNALCOL001",
                        "Multiple colors.json files found",
                        "Multiple colors.json files were found. Only the first one will be used.",

View on GitHub (pinned to 0acc92fada)

Solutions

  1. Run a clean rebuild (dotnet clean && dotnet build) to re-read the AdditionalFiles
  2. Verify the colors.json referenced by the Spectre.Console source generator exists on disk and is readable
  3. Reinstall/restore the Spectre.Console package so its bundled colors.json is refreshed
  4. Check for file locks from antivirus or another IDE process holding colors.json

Example fix

# before: stale/locked AdditionalFiles causes generation failure
# after: force a clean generation
dotnet clean
dotnet restore
dotnet build
Defensive patterns

Strategy: validation

Validate before calling

// Pre-build check: confirm the colors.json AdditionalFiles item resolves
dotnet msbuild -getItem:AdditionalFiles | findstr colors.json

Prevention

When it happens

Trigger: The colors.json AdditionalFiles item exists in the project graph but Roslyn cannot retrieve its text (locked, deleted between itemization and generation, unreadable, or empty/garbled).

Common situations: Corrupted or hand-edited Spectre.Console source-generator data file; antivirus/IDE file lock; partial git checkout; restoring a package whose colors.json is missing or zero-byte; a broken AdditionalFiles path glob.

Related errors


AI-assisted analysis of spectreconsole/spectre.console@0acc92fada (2026-08-13). Data as JSON: /api/errors/cd0522d826171f6c. Report an issue: GitHub.