dotnet/machinelearning · error · InvalidOperationException

Current estimator chain has no estimator, can't append cache

Error message

Current estimator chain has no estimator, can't append cache checkpoint.

What it means

EstimatorChain<TLastTransformer>.AppendCacheCheckpoint adds a caching checkpoint to an estimator chain, but the chain must contain at least one estimator. Calling it on a freshly created empty EstimatorChain<TTrans> throws InvalidOperationException since there is nothing to append caching after.

Source

Thrown at src/Microsoft.ML.Data/DataLoadSave/EstimatorChain.cs:113

            return new EstimatorChain<TNewTrans>(_host, _estimators.AppendElement(estimator), _scopes.AppendElement(scope), _needCacheAfter.AppendElement(false));
        }

        /// <summary>
        /// Append a 'caching checkpoint' to the estimator chain. This will ensure that the downstream estimators will be trained against
        /// cached data. It is helpful to have a caching checkpoint before trainers or feature engineering that take multiple data passes.
        /// It is also helpful to have after a slow operation, for example after dataset loading from a slow source or after feature
        /// engineering that is slow on its apply phase, if downstream estimators will do multiple passes over the output of this operation.
        /// Adding a cache checkpoint at the begin or end of an <see cref="EstimatorChain{TLastTransformer}"/> is meaningless and should be avoided.
        /// Cache checkpoints should be removed if disk thrashing or OutOfMemory exceptions are seen, which can occur on when the featured
        /// dataset immediately prior to the checkpoint is larger than available RAM.
        /// </summary>
        /// <param name="env">The host environment to use for caching.</param>
        public EstimatorChain<TLastTransformer> AppendCacheCheckpoint(IHostEnvironment env)
        {
            Contracts.CheckValue(env, nameof(env));

            if (_estimators.Length == 0)
                throw new InvalidOperationException("Current estimator chain has no estimator, can't append cache checkpoint.");

            if (_needCacheAfter.Last())
            {
                // If we already need to cache after this, we don't need to do anything else.
                return this;
            }

            bool[] newNeedCache = _needCacheAfter.ToArray();
            newNeedCache[newNeedCache.Length - 1] = true;
            return new EstimatorChain<TLastTransformer>(env, _estimators, _scopes, newNeedCache);
        }
    }
}

View on GitHub (pinned to 7b76e69cf9)

Solutions

  1. Move the AppendCacheCheckpoint call after the first Append(...) on the chain
  2. Guard the call with a check that the chain already has estimators (e.g. track pipeline build order)
  3. If the chain is conditionally empty, skip caching entirely for the empty-chain case

Example fix

// before
var chain = new EstimatorChain<ITransformer>().AppendCacheCheckpoint(env);
// after
var chain = new EstimatorChain<ITransformer>()
    .Append(firstEstimator)
    .AppendCacheCheckpoint(env);
Defensive patterns

Strategy: validation

Validate before calling

if (estimatorsAppended == 0) return chain; // skip cache on empty chain
chain = chain.AppendCacheCheckpoint(env);

Try / catch

try { chain = chain.AppendCacheCheckpoint(env); }
catch (InvalidOperationException ex) when (ex.Message.Contains("no estimator"))
{ /* skip caching for empty chain */ }

Prevention

When it happens

Trigger: Creating a new EstimatorChain<TTransformer>() and calling AppendCacheCheckpoint(env) as the first operation, before any Append call has added an estimator.

Common situations: Dynamically building ML.NET pipelines where the cache call is emitted unconditionally before appending estimators; refactored pipelines that accidentally start with the cache checkpoint; generated code templates that always call AppendCacheCheckpoint first.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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