tui-cs/Terminal.Gui · error · InvalidOperationException
T must be a numeric type that supports addition and subtract
Error message
T must be a numeric type that supports addition and subtraction.
What it means
Thrown by the NumericUpDown<T> constructor when T is not 'object' and NumericHelper.SupportsType(type) returns false — i.e. T is a type without addition/subtraction operators that the helper recognises. NumericUpDown needs to add/subtract the increment, so unsupported generic type arguments are rejected at construction rather than failing later on every keystroke.
Source
Thrown at Terminal.Gui/Views/NumericUpDown.cs:66
private readonly ScrollButton _up;
private View _number;
private TextField? _editor;
private bool _updatingText;
private bool _editingFromUser;
private bool _canEdit;
/// <summary>
/// Initializes a new instance of the <see cref="NumericUpDown{T}"/> class.
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
public NumericUpDown ()
{
Type type = typeof (T);
if (!(type == typeof (object) || NumericHelper.SupportsType (type)))
{
throw new InvalidOperationException ("T must be a numeric type that supports addition and subtraction.");
}
CanFocus = true;
Width = Dim.Auto (DimAutoStyle.Content);
Height = Dim.Auto (DimAutoStyle.Content);
_down = new ScrollButton
{
Orientation = Orientation.Vertical,
Direction = NavigationDirection.Forward
};
_number = CreateNumberView ();
_up = new ScrollButton
{
X = Pos.Right (_number),View on GitHub (pinned to 2e47b11478)
Solutions
- Use a supported numeric type: int, long, decimal, double, float, etc. — check NumericHelper.SupportsType for the exact list.
- For enums use OptionSelectorTEnum; for flags use FlagSelectorTEnum.
- If a custom numeric struct is required, ensure it exposes matching +/- operators and register/support it via the helper's accepted set, or wrap a supported primitive.
Example fix
// before var nud = new NumericUpDown<MyEnum>(); // throws 168 // after var nud = new NumericUpDown<int>(); // and for enums prefer: var sel = new OptionSelectorTEnum<MyEnum>();
Defensive patterns
Strategy: type-guard
Validate before calling
Type t = typeof(T);
if (!(t == typeof(object) || NumericHelper.SupportsType(t)))
{
// pick a supported numeric type, or use OptionSelector for enums
} Type guard
static bool SupportsNumericUpDown<T>() =>
typeof(T) == typeof(object) || NumericHelper.SupportsType(typeof(T)); Prevention
- Use int/long/decimal/double/float for NumericUpDown<T>.
- Use OptionSelectorTEnum for enums, FlagSelectorTEnum for flags.
- Check NumericHelper.SupportsType before binding a generic type argument.
When it happens
Trigger: Constructing NumericUpDown<SomeEnum>, NumericUpDown<string>, NumericUpDown<CustomStruct> (no matching operators), or NumericUpDown<Guid>. Supported types are the numeric primitives handled by NumericHelper.
Common situations: Trying to use NumericUpDown for an enum (use OptionSelector/FlagSelector instead); wrapping a domain value type that lacks operator overloads; copy-pasting NumericUpDown<double> into a custom value-object generic.
Related errors
- The source stream must be seekable (CanSeek property)
- Zoom level must be a finite number.
- Maximum sixel palette colors must be greater than zero.
- value
- value
AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13).
Data as JSON: /api/errors/33eb8ce1385a848e.
Report an issue: GitHub.