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

  1. Map the column to `string` and validate/truncate in code rather than forcing a char.
  2. Fix the source data so the column only ever contains a single character.
  3. Use a custom ITypeHandler to define the conversion (e.g. take the first character).
  4. 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

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


AI-assisted analysis of DapperLib/Dapper@72a54c475f (2026-08-13). Data as JSON: /api/errors/b759a7bde79f8019. Report an issue: GitHub.