dotnet/machinelearning · error · ArgumentException

result must be of type {typeof(TrialResult<TMetrics>)}

Error message

result must be of type {typeof(TrialResult<TMetrics>)}

What it means

The generic monitor's ReportBestTrial expects the incoming result to be a TrialResult<TMetrics>; if the runtime type does not match, the pattern-match fails and ArgumentException is thrown. It guards the best-run tracking against results produced by a differently-typed runner.

Source

Thrown at src/Microsoft.ML.AutoML/AutoMLExperiment/IMonitor.cs:95

            this.RunDetails = new List<TrialResult<TMetrics>>();
        }

        public event EventHandler<TrialResult<TMetrics>> OnTrialCompleted;

        public List<TrialResult<TMetrics>> RunDetails { get; }

        public TrialResult<TMetrics> BestRun { get; private set; }

        public override void ReportBestTrial(TrialResult result)
        {
            base.ReportBestTrial(result);
            if (result is TrialResult<TMetrics> binaryClassificationResult)
            {
                BestRun = binaryClassificationResult;
            }
            else
            {
                throw new ArgumentException($"result must be of type {typeof(TrialResult<TMetrics>)}");
            }
        }

        public override void ReportCompletedTrial(TrialResult result)
        {
            base.ReportCompletedTrial(result);
            if (result is TrialResult<TMetrics> metricResult)
            {
                RunDetails.Add(metricResult);
                OnTrialCompleted?.Invoke(this, metricResult);
            }
            else
            {
                throw new ArgumentException($"result must be of type {typeof(TrialResult<TMetrics>)}");
            }
        }

        public override void ReportFailTrial(TrialSettings settings, Exception exp)

View on GitHub (pinned to 7b76e69cf9)

Solutions

  1. Ensure the runner paired with this monitor produces TrialResult<TMetrics> with the same TMetrics as the monitor.
  2. Pass the typed result from the generic evaluation path, not a base TrialResult.
  3. Add an is TrialResult<TMetrics> check at the call site before invoking ReportBestTrial.
  4. Fix generic type inference so monitor and runner share the same TMetrics.

Example fix

// before
TrialResult result = runner.Evaluate(); // base type
monitor.ReportBestTrial(result); // ArgumentException
// after
if (runner.Evaluate() is TrialResult<BinaryClassificationMetrics> typed)
{
    monitor.ReportBestTrial(typed);
}
Defensive patterns

Strategy: type-guard

Validate before calling

// before raising the callback:
if (result is not TrialResult<TMetrics> typed)
    throw new InvalidOperationException($"Runner must emit TrialResult<{typeof(TMetrics).Name}> for this monitor");

Type guard

bool IsTypedResult<TMetrics>(TrialResult r) => r is TrialResult<TMetrics>;

Try / catch

try { monitor.ReportBestTrial(result); }
catch (ArgumentException ex) when (ex.Message.Contains("must be of type")) { log.LogError(ex, "Runner/monitor generic type mismatch"); throw; }

Prevention

When it happens

Trigger: Calling ReportBestTrial on a TrialHTMonitor<TMetrics> (or subclass) with a base TrialResult or a TrialResult<OtherTMetrics> - typically when the runner and monitor are generic-parameterized inconsistently.

Common situations: Mixing monitors/runners built for different metric types (e.g. binary vs regression TrialResult); custom runner code raising best-trial callbacks with non-generic results; refactorings that erased generic type arguments.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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