microsoft/garnet · error · TsavoriteException

Transactional consistent read context does not reset ResetMo

Error message

Transactional consistent read context does not reset ResetModified!

What it means

The Delete overload with DeleteOptions (line 379) and the ResetModified method (line 384) both reject calls on the TransactionalConsistentReadContext. This entry maps to ResetModified (message 'does not reset ResetModified!'): because the read-only context never tracks per-key modifications, clearing the modified flag is meaningless and throws. ResetModified is only supported on the write-capable contexts.

Source

Thrown at libs/storage/Tsavorite/cs/src/core/ClientSession/TransactionalConsistentReadContext.cs:384

        /// <inheritdoc/>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public Status RMW(TKey key, ref TInput input, ref RMWOptions rmwOptions, TContext userContext = default)
            => throw new TsavoriteException("Transactional consistent read context does not allow writes!");

        /// <inheritdoc/>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public Status Delete(TKey key, TContext userContext = default)
            => throw new TsavoriteException("Transactional consistent read context does not allow writes!");

        /// <inheritdoc/>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public Status Delete(TKey key, ref DeleteOptions deleteOptions, TContext userContext = default)
            => throw new TsavoriteException("Transactional consistent read context does not allow writes!");

        /// <inheritdoc/>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void ResetModified(TKey key)
            => throw new TsavoriteException("Transactional consistent read context does not reset ResetModified!");

        /// <inheritdoc/>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        internal bool IsModified(TKey key)
            => throw new TsavoriteException("Transactional consistent read context does not allow IsModified!");

        /// <inheritdoc/>
        public void Refresh()
            => throw new TsavoriteException("Transactional consistent read context does not Refresh!");

        #endregion ITsavoriteContext
    }
}

View on GitHub (pinned to 951b0fc683)

Solutions

  1. Use session.TransactionalUnsafeContext for ResetModified (implemented at TransactionalUnsafeContext.cs:498) and for DeleteOptions Delete (TransactionalUnsafeContext.cs:484).
  2. Use a non-transactional write context if isolation is not needed.
  3. Do not call modification-tracking methods on read-only consistent read contexts.

Example fix

// before
var tcr = session.TransactionalConsistentReadContext;
tcr.ResetModified(key); // throws

// after
var luc = session.TransactionalUnsafeContext;
luc.BeginUnsafe();
try { luc.ResetModified(key); }
finally { luc.EndUnsafe(); }
Defensive patterns

Strategy: validation

Validate before calling

// Modification tracking belongs on a write-capable context.
var w = session.TransactionalUnsafeContext;
w.BeginUnsafe();
try { w.ResetModified(key); }
finally { w.EndUnsafe(); }
// (DeleteOptions Delete likewise: w.Delete(key, ref deleteOptions).)

Type guard

static bool IsReadOnlyContext<TCtx>() => typeof(TCtx).Name.Contains("ConsistentReadContext");
// Assert before ResetModified/Delete(deleteOptions) calls.

Prevention

When it happens

Trigger: Calling tcrContext.ResetModified(TKey key) (and, relatedly, tcrContext.Delete(key, ref DeleteOptions)) on the transactional consistent read context, typically to clear a modification marker after handling a record.

Common situations: Code that interplays with UnsafeContext.IsModified/ResetModified semantics is copied into a transactional consistent-read scope; the read-only context has no modified-flag state to reset.

Related errors


AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13). Data as JSON: /api/errors/ff9f8fc395edbdfb. Report an issue: GitHub.