dotnet/machinelearning · error · System.ArgumentException
Decimal separator cannot match the column separator
Error message
Decimal separator cannot match the column separator
What it means
SaveCsv writes columns separated by 'separator'; if the culture's NumberDecimalSeparator equals that separator, numeric values would be indistinguishable from column boundaries, corrupting the CSV. SaveCsv therefore throws ArgumentException('Decimal separator cannot match the column separator').
Source
Thrown at src/Microsoft.Data.Analysis/DataFrame.IO.cs:663
/// </summary>
/// <param name="dataFrame"><see cref="DataFrame"/></param>
/// <param name="csvStream">stream of CSV data to be write out</param>
/// <param name="separator">column separator</param>
/// <param name="header">has a header or not</param>
/// <param name="encoding">the character encoding. Defaults to UTF8 if not specified</param>
/// <param name="cultureInfo">culture info for formatting values</param>
public static void SaveCsv(DataFrame dataFrame, Stream csvStream,
char separator = ',', bool header = true,
Encoding encoding = null, CultureInfo cultureInfo = null)
{
if (cultureInfo is null)
{
cultureInfo = CultureInfo.CurrentCulture;
}
if (cultureInfo.NumberFormat.NumberDecimalSeparator.Equals(separator.ToString()))
{
throw new ArgumentException("Decimal separator cannot match the column separator");
}
if (encoding is null)
{
encoding = Encoding.ASCII;
}
using (StreamWriter csvFile = new StreamWriter(csvStream, encoding, bufferSize: DefaultStreamReaderBufferSize, leaveOpen: true))
{
if (dataFrame != null)
{
if (header)
{
SaveHeader(csvFile, dataFrame.Columns.GetColumnNames(), separator);
}
var record = new StringBuilder();
View on GitHub (pinned to 7b76e69cf9)
Solutions
- Pass a cultureInfo whose decimal separator differs from the separator, e.g. CultureInfo.InvariantCulture
- Use ';' as the field separator when targeting a comma-decimal culture
- Force the decimal format explicitly instead of relying on CurrentCulture
- Pre-validate the two separators in caller code before calling SaveCsv
Example fix
// before df.SaveCsv(path, separator: ','); // de-DE machine: decimal sep is ',' // after df.SaveCsv(path, separator: ',', cultureInfo: CultureInfo.InvariantCulture);
Defensive patterns
Strategy: validation
Validate before calling
var ci = cultureInfo ?? CultureInfo.CurrentCulture;
if (ci.NumberFormat.NumberDecimalSeparator.Equals(separator.ToString()))
cultureInfo = CultureInfo.InvariantCulture; Try / catch
try { df.SaveCsv(path, separator: separator, cultureInfo: cultureInfo); } catch (ArgumentException ex) when (ex.Message.Contains("Decimal separator")) { df.SaveCsv(path, separator: ';', cultureInfo: cultureInfo); } Prevention
- Always pass CultureInfo.InvariantCulture for machine-readable CSV
- Prefer ';' separators in comma-decimal locales
- Test CSV exports under multiple regional settings
When it happens
Trigger: Calling SaveCsv with separator ',' (or '.') combined with a culture whose NumberDecimalSeparator is the same character — classically a European culture where the decimal separator is ',' while writing comma-separated CSV, e.g. SaveCsv(df, path, separator: ',', cultureInfo: new CultureInfo("de-DE")).
Common situations: European locales writing comma-delimited CSV; hardcoding separator ',' while relying on CultureInfo.CurrentCulture that uses ',' decimals; machines with regional settings differing from dev machines.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Expected either {0} or {1} to be provided
- Expected a seekable stream
- LessColumnsThatExpected
- Exception of type 'System.ArgumentException' was thrown.
- kind
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/09475b8f3dc32d58.
Report an issue: GitHub.