dotnet/machinelearning · error · System.ArgumentNullException

Value cannot be null. (Parameter 'row')

Error message

Value cannot be null. (Parameter 'row')

What it means

DataFrame.Append(DataFrameRow row, ...) throws ArgumentNullException(nameof(row)) when the row is null (message: "Value cannot be null. (Parameter 'row')"). The method must enumerate the row's key/value pairs to map values onto columns, so a null row is rejected before any work. In this source region it appears in the in-place Append path after the ret DataFrame is resolved.

Source

Thrown at src/Microsoft.Data.Analysis/DataFrame.cs:621

        /// <summary> 
        /// Appends a row by enumerating column names and values from <paramref name="row"/> 
        /// </summary> 
        /// <remarks>If a column's value doesn't match its column's data type, a conversion will be attempted</remarks> 
        /// <param name="row">An enumeration of column name and value to be appended</param> 
        /// <param name="inPlace">If set, appends <paramref name="row"/> in place. Otherwise, a new DataFrame is returned with an appended <paramref name="row"/> </param>
        /// <param name="cultureInfo">Culture info for formatting values</param>
        public DataFrame Append(IEnumerable<KeyValuePair<string, object>> row, bool inPlace = false, CultureInfo cultureInfo = null)
        {
            if (cultureInfo == null)
            {
                cultureInfo = CultureInfo.CurrentCulture;
            }

            DataFrame ret = inPlace ? this : Clone();
            if (row == null)
            {
                throw new ArgumentNullException(nameof(row));
            }

            List<object> cachedObjectConversions = new List<object>();
            foreach (KeyValuePair<string, object> columnAndValue in row)
            {
                string columnName = columnAndValue.Key;
                int index = ret.Columns.IndexOf(columnName);
                if (index == -1)
                {
                    throw new ArgumentException(String.Format(Strings.InvalidColumnName, columnName), nameof(columnName));
                }

                DataFrameColumn column = ret.Columns[index];
                object value = columnAndValue.Value;
                if (value != null)
                {
                    value = Convert.ChangeType(value, column.DataType, cultureInfo);
                    if (value is null)

View on GitHub (pinned to 7b76e69cf9)

Solutions

  1. Guard the call: if (row != null) df.Append(row); — skip or log null rows explicitly.
  2. Fix the row-producing code so it never returns null (throw or substitute an empty DataFrameRow).
  3. Catch ArgumentNullException around Append to identify which batch entry was missing.
  4. Use FirstOrDefault carefully — check for null before appending its result.

Example fix

// before
foreach (var r in parsedRows)
    df.Append(r); // r may be null
// after
foreach (var r in parsedRows)
{
    if (r == null) { logSkip(); continue; }
    df.Append(r);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (row == null) { logger.LogWarning("Skipping null row"); return; }
df.Append(row);

Type guard

bool CanAppend(DataFrameRow row) => row is not null;

Try / catch

try { df.Append(row); }
catch (ArgumentNullException ex) { logger.LogError(ex, "Null row passed to Append"); throw; }

Prevention

When it happens

Trigger: Calling df.Append(null) or appending the result of a row factory/lookup that returned null (e.g. rows.ElementAt(i) out of range, a failed parse returning null).

Common situations: Looping over a collection of rows where some entries are null (sparse data, filtered source); a builder method that returns null on invalid input instead of throwing; LINQ FirstOrDefault returning null.

Related errors


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