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
- Run a clean rebuild (dotnet clean && dotnet build) to re-read the AdditionalFiles
- Verify the colors.json referenced by the Spectre.Console source generator exists on disk and is readable
- Reinstall/restore the Spectre.Console package so its bundled colors.json is refreshed
- 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
- Keep the shipped colors.json intact; do not hand-edit generator data
- Add a CI step that fails if any Spectre.Console data file is zero-byte or missing
- Close IDEs/antivirus that may lock AdditionalFiles during build
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
- Failed to read emoji.json at {file.Path}
- Failed to read spinners_default.json at {file.Path}
- Failed to read spinners_sindresorhus.json at {file.Path}
- Color {number} has null name
- Color {number} has null alias
AI-assisted analysis of spectreconsole/spectre.console@0acc92fada (2026-08-13).
Data as JSON: /api/errors/cd0522d826171f6c.
Report an issue: GitHub.