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').

Solutions

  1. Pass a cultureInfo whose decimal separator differs from the separator, e.g. CultureInfo.InvariantCulture
  2. Use ';' as the field separator when targeting a comma-decimal culture
  3. Force the decimal format explicitly instead of relying on CurrentCulture
  4. 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

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


AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11). Data as JSON: /api/errors/09475b8f3dc32d58. Report an issue: GitHub.

Appendix: 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)