spectreconsole/spectre.console · error · InvalidOperationException
Failed to read spinners_sindresorhus.json at {file.Path}
Error message
Failed to read spinners_sindresorhus.json at {file.Path} What it means
Thrown inside the spinner source generator when an AdditionalFiles entry ending in spinners_sindresorhus.json matched but GetText returned null. Same shape as the default-spinner read failure; it surfaces as a compile-time InvalidOperationException in the generator pipeline.
Source
Thrown at src/Spectre.Console.SourceGenerator/Spinners/SpinnerGenerator.cs:38
public void Initialize(IncrementalGeneratorInitializationContext context)
{
// Find spinners_default.json
// Step 1: Extract text (cached by string value equality)
// Step 2: Wrap in EquatableArray for value equality when combining
var defaultSpinners = context.AdditionalTextsProvider
.Where(static file => file.Path.EndsWith("spinners_default.json", StringComparison.OrdinalIgnoreCase))
.Select(static (file, ct) =>
file.GetText(ct)?.ToString()
?? throw new InvalidOperationException($"Failed to read spinners_default.json at {file.Path}"))
.Collect()
.Select(static (arr, _) => new EquatableArray<string>(arr));
// Find spinners_sindresorhus.json
var sindreSpinners = context.AdditionalTextsProvider
.Where(static file => file.Path.EndsWith("spinners_sindresorhus.json", StringComparison.OrdinalIgnoreCase))
.Select(static (file, ct) =>
file.GetText(ct)?.ToString()
?? throw new InvalidOperationException($"Failed to read spinners_sindresorhus.json at {file.Path}"))
.Collect()
.Select(static (arr, _) => new EquatableArray<string>(arr));
// Combine both JSON files and parse in the pipeline (for caching)
// EquatableArray has value equality, so this step is properly cached
var spinners = defaultSpinners.Combine(sindreSpinners)
.Select(static (data, _) =>
{
var (defaultJsonFiles, sindreJsonFiles) = data;
if (defaultJsonFiles.IsEmpty || sindreJsonFiles.IsEmpty)
{
return EquatableArray<SpinnerModel>.Empty;
}
var parsedSpinners = SpinnerParser.ParseAll(defaultJsonFiles[0], sindreJsonFiles[0]);
var validSpinners = parsedSpinners
.Where(IsValidSpinner)
.ToArray();View on GitHub (pinned to 0acc92fada)
Solutions
- Clean rebuild (dotnet clean && dotnet build) to re-read AdditionalFiles
- Confirm spinners_sindresorhus.json exists and is readable on disk
- Restore/reinstall the Spectre.Console package to refresh the file
- Release any process lock on spinners_sindresorhus.json
Example fix
# before: spinners_sindresorhus.json unreadable during generation # after: clean generation dotnet clean dotnet restore dotnet build
Defensive patterns
Strategy: validation
Validate before calling
// Pre-build check: confirm spinners_sindresorhus.json AdditionalFiles item resolves dotnet msbuild -getItem:AdditionalFiles | findstr spinners_sindresorhus.json
Prevention
- Do not hand-edit generator data files
- CI step failing on zero-byte/missing data files prevents broken builds
When it happens
Trigger: The spinners_sindresorhus.json AdditionalFiles item is in the graph but its text cannot be read at generation time (locked, deleted mid-build, unreadable, empty).
Common situations: Corrupted spinners_sindresorhus.json; antivirus/IDE lock; partial checkout; package restore that left the file missing or zero-byte.
Related errors
- Failed to read spinners_default.json at {file.Path}
- Failed to read colors.json at {file.Path}
- Failed to read emoji.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/d116e8b33a3f80dc.
Report an issue: GitHub.