DapperLib/Dapper · error · ArgumentException
A single-character was expected
Error message
A single-character was expected
What it means
Thrown by `SqlMapper.ReadChar(object value)` when the value is neither null/DBNull nor a single-character string nor a `char`. ReadChar accepts only those three shapes; anything else (a multi-char string, a number, a byte, etc.) cannot be unambiguously converted to one character, so it throws ArgumentException.
Source
Thrown at Dapper/SqlMapper.cs:2080
values[iter] = obj is DBNull ? null! : obj;
}
}
return new DapperRow(table, values);
};
}
/// <summary>
/// Internal use only.
/// </summary>
/// <param name="value">The object to convert to a character.</param>
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete(ObsoleteInternalUsageOnly, false)]
public static char ReadChar(object value)
{
if (value is null || value is DBNull) throw new ArgumentNullException(nameof(value));
if (value is string s && s.Length == 1) return s[0];
if (value is char c) return c;
throw new ArgumentException("A single-character was expected", nameof(value));
}
/// <summary>
/// Internal use only.
/// </summary>
/// <param name="value">The object to convert to a character.</param>
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete(ObsoleteInternalUsageOnly, false)]
public static char? ReadNullableChar(object value)
{
if (value is null || value is DBNull) return null;
if (value is string s && s.Length == 1) return s[0];
if (value is char c) return c;
throw new ArgumentException("A single-character was expected", nameof(value));
}
/// <summary>
View on GitHub (pinned to 72a54c475f)
Solutions
- Map the column to `string` and validate/truncate in code rather than forcing a char.
- Fix the source data so the column only ever contains a single character.
- Use a custom ITypeHandler to define the conversion (e.g. take the first character).
- Coalesce/substring in SQL: `substring(code, 1, 1)`.
Example fix
// before
public class Row { public char Code { get; set; } } // 'AB' from DB throws
// after
public class Row { public string Code { get; set; } } Defensive patterns
Strategy: type-guard
Validate before calling
// Verify single-char shape before relying on char mapping. static bool IsSingleChar(object? v) => v is char || (v is string s && s.Length == 1);
Type guard
static char ToChar(object? v) => v switch { null => throw new ArgumentNullException(nameof(v)), DBNull => throw new ArgumentNullException(nameof(v)), char c => c, string s when s.Length == 1 => s[0], _ => throw new ArgumentException("not a single char") }; Prevention
- Map multi-character string columns to string, not char.
- Constrain/validate source data for char-typed columns.
- Use a custom type handler for non-standard conversions.
When it happens
Trigger: A column mapped to `char` returns a string longer than one character, or a numeric/other type. Dapper routes the cell value through ReadChar (char parser at SqlMapper.cs:3100) and the value fails both the `string s && s.Length == 1` and `char c` checks. Direct calls like `SqlMapper.ReadChar("ab")` or `SqlMapper.ReadChar(65)` also trigger it.
Common situations: A varchar code field that occasionally holds multiple characters being mapped to `char`; a schema change widening a column; storing numeric codes in a column mapped to char.
Related errors
- The type '{value.GetType().Name}' is not supported for SQL l
- The Rest field of a ValueTuple must contain a nested ValueTu
- A parameterless default constructor or one matching signatur
- type
- Property setting not found for: {name}
AI-assisted analysis of DapperLib/Dapper@72a54c475f (2026-08-13).
Data as JSON: /api/errors/b759a7bde79f8019.
Report an issue: GitHub.