spectreconsole/spectre.console · error · InvalidOperationException
At least one column must be specified.
Error message
At least one column must be specified.
What it means
Thrown by the Progress.Columns(this Progress, params ProgressColumn[]) extension method when the columns array is empty. Progress requires at least one column to render anything meaningful (e.g., TaskDescriptionColumn, ProgressBarColumn, PercentageColumn). Calling Columns() with no arguments produces a zero-length array via params, triggering the !columns.Any() guard.
Source
Thrown at src/Spectre.Console/Live/Progress/Progress.cs:198
/// Contains extension methods for <see cref="Progress"/>.
/// </summary>
public static class ProgressExtensions
{
/// <summary>
/// Sets the columns to be used for an <see cref="Progress"/> instance.
/// </summary>
/// <param name="progress">The <see cref="Progress"/> instance.</param>
/// <param name="columns">The columns to use.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Progress Columns(this Progress progress, params ProgressColumn[] columns)
{
ArgumentNullException.ThrowIfNull(progress);
ArgumentNullException.ThrowIfNull(columns);
if (!columns.Any())
{
throw new InvalidOperationException("At least one column must be specified.");
}
progress.Columns.Clear();
progress.Columns.AddRange(columns);
return progress;
}
/// <summary>
/// Sets an optional hook to intercept rendering.
/// </summary>
/// <param name="progress">The <see cref="Progress"/> instance.</param>
/// <param name="renderHook">The custom render function.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Progress UseRenderHook(this Progress progress, Func<IRenderable, IReadOnlyList<ProgressTask>, IRenderable> renderHook)
{
progress.RenderHook = renderHook;
View on GitHub (pinned to 0acc92fada)
Solutions
- Pass at least one ProgressColumn, e.g., .Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
- If building columns dynamically, ensure the collection is non-empty before calling Columns.
- Default to the built-in column set and only override when you have at least one column.
Example fix
// before
var progress = AnsiConsole.Progress().Columns();
// after
var progress = AnsiConsole.Progress()
.Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()); Defensive patterns
Strategy: validation
Validate before calling
// Ensure at least one column
var columns = BuildColumns();
if (columns.Length == 0)
{
columns = new ProgressColumn[]
{
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new PercentageColumn(),
};
}
AnsiConsole.Progress().Columns(columns); Type guard
static bool HasAtLeastOneColumn(ProgressColumn[] columns)
=> columns is { Length: > 0 }; Prevention
- Default to the standard column set when building dynamically.
- Validate columns array is non-empty before passing to Columns().
- Audit refactoring that removes column arguments from a fluent chain.
When it happens
Trigger: Calling AnsiConsole.Progress().Columns() with no arguments, or calling .Columns(someArray) where someArray is empty. This can also happen if columns are conditionally filtered out before being passed.
Common situations: Dynamically building the columns list from configuration and passing an empty list; refactoring that accidentally removes all column arguments; calling Columns() in a fluent chain where the params overload is invoked with zero args by mistake.
Related errors
- Stopped tasks cannot be restarted
- Task name cannot be empty.
- Console width must be greater than zero
- Console height must be greater than zero
- Output writer was null
AI-assisted analysis of spectreconsole/spectre.console@0acc92fada (2026-08-13).
Data as JSON: /api/errors/ed42e465a685ed48.
Report an issue: GitHub.