spectreconsole/spectre.console · error · InvalidOperationException
Could not convert input to a string
Error message
Could not convert input to a string
What it means
Thrown by TypeConverterHelper.ConvertToString<T>(T input) when the TypeConverter for type T returns null from ConvertToInvariantString. This is an internal helper used by Spectre.Console to stringify choice values in prompts (e.g., TextPrompt<T> with choices). The built-in TypeDescriptor system should normally return a non-null string for most types, but custom types with misconfigured TypeConverters, or exotic types without a registered converter, can return null.
Source
Thrown at src/Spectre.Console/Internal/TypeConverterHelper.cs:15
namespace Spectre.Console;
internal static class TypeConverterHelper
{
internal const DynamicallyAccessedMemberTypes ConverterAnnotation = DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields;
internal static bool IsGetConverterSupported =>
!AppContext.TryGetSwitch("Spectre.Console.TypeConverterHelper.IsGetConverterSupported ", out var enabled) || enabled;
public static string ConvertToString<T>(T input)
{
var result = GetTypeConverter<T>().ConvertToInvariantString(input);
if (result == null)
{
throw new InvalidOperationException("Could not convert input to a string");
}
return result;
}
public static bool TryConvertFromString<T>(string input, [MaybeNull] out T? result)
{
try
{
result = (T?)GetTypeConverter<T>().ConvertFromInvariantString(input);
return true;
}
catch
{
result = default;
return false;
}
}View on GitHub (pinned to 0acc92fada)
Solutions
- Provide an explicit converter or ToString override on your custom type so ConvertToInvariantString never returns null.
- Decorate your type with [TypeConverter(typeof(MyConverter))] that returns a non-null string.
- For prompt choices, use simpler types (string, int, enum) that have reliable built-in converters.
- If the type legitimately cannot stringify, provide a custom display via the prompt's converter parameter instead of relying on TypeConverterHelper.
Example fix
// before
public record MyId(Guid Value);
var choice = AnsiConsole.Prompt(
new SelectionPrompt<MyId>().AddChoices(ids));
// after
[TypeConverter(typeof(MyIdConverter))]
public record MyId(Guid Value);
public class MyIdConverter : TypeConverter
{
public override object? ConvertTo(ITypeDescriptorContext? ctx, CultureInfo? c, object value, Type dest)
=> value is MyId id ? id.Value.ToString() : null;
} Defensive patterns
Strategy: validation
Validate before calling
// Test string conversion before using as prompt choice
var testString = TypeDescriptor.GetConverter(typeof(T))
?.ConvertToInvariantString(sampleValue);
if (testString is null)
{
throw new InvalidOperationException(
$"Type {typeof(T).Name} cannot be converted to string for prompt display.");
} Type guard
static bool HasStringRepresentation<T>(T sample)
{
try
{
var converter = TypeDescriptor.GetConverter(typeof(T));
return converter?.ConvertToInvariantString(sample) is not null;
}
catch
{
return false;
}
} Try / catch
try
{
var prompt = new SelectionPrompt<T>().AddChoices(items);
return AnsiConsole.Prompt(prompt);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("convert input to a string"))
{
// Fallback: provide a custom converter to the prompt
var prompt = new SelectionPrompt<T>()
.Converter(myConverter)
.AddChoices(items);
return AnsiConsole.Prompt(prompt);
} Prevention
- Use types with reliable string conversion (primitives, enums, records with ToString) as prompt generics.
- Decorate custom types with [TypeConverter] that never returns null.
- Override ToString on custom choice types.
- Provide an explicit .Converter(lambda) to SelectionPrompt/TextPrompt to bypass TypeConverterHelper entirely.
When it happens
Trigger: Using a SelectionPrompt or TextPrompt with a generic type T whose TypeDescriptor.GetConverter / custom TypeConverterAttribute returns null from ConvertToInvariantString. Also possible if T is a type that has no standard string representation and the fallback TypeConverter yields null.
Common situations: Custom enum or record type used as a prompt choice without a working TypeConverter; third-party types whose TypeConverterAttribute points to a converter that returns null; edge cases with nullable value types or interfaces used as prompt generics; trimming/AOT scenarios where reflection-based converter discovery is suppressed.
Related errors
- Failed to read input in non-interactive mode.
- At least one column must be specified.
- Stopped tasks cannot be restarted
- Task name cannot be empty.
- Console width must be greater than zero
AI-assisted analysis of spectreconsole/spectre.console@0acc92fada (2026-08-13).
Data as JSON: /api/errors/b903dce4d4f1abc0.
Report an issue: GitHub.