dotnet/wpf · error · ArgumentException

SR.ModificationEarlierThanCreation

Error message

SR.ModificationEarlierThanCreation

What it means

Annotation's constructor enforces that lastModificationTime is not earlier than creationTime, throwing ArgumentException with SR.ModificationEarlierThanCreation. The annotation's audit timestamps must be chronologically consistent. Passing a modification time before creation violates this invariant.

Solutions

  1. Pass timestamps in a consistent order: modified must be >= created
  2. Normalize both values to UTC (DateTimeKind.Utc) before constructing
  3. Clamp lastModificationTime to creationTime when loading legacy data: use DateTimeHelper.Max

Example fix

// before
var ann = new Annotation(type, id, DateTime.Now, storedModifiedTime /* older, local time */);
// after
DateTime created = storedCreatedTime.ToUniversalTime();
DateTime modified = storedModifiedTime.ToUniversalTime();
if (modified < created) modified = created;
var ann = new Annotation(type, id, created, modified);
Defensive patterns

Strategy: validation

Validate before calling

DateTime created = creationTime.ToUniversalTime();
DateTime modified = lastModificationTime.ToUniversalTime();
if (modified < created) modified = created;
var annotation = new Annotation(type, id, created, modified);

Type guard

bool AreTimesConsistent(DateTime created, DateTime modified) => modified >= created;

Try / catch

try
{
    var ann = new Annotation(type, id, created, modified);
}
catch (ArgumentException ex)
{
    logger.LogWarning(ex, "Annotation timestamps inconsistent; clamping modified time");
    modified = created;
    ann = new Annotation(type, id, created, modified);
}

Prevention

When it happens

Trigger: Calling the public Annotation constructor where lastModificationTime.CompareTo(creationTime) < 0, e.g. creationTime = DateTime.Now and lastModificationTime = an earlier stored time, or mixing UTC and local DateTime values.

Common situations: Loading annotations persisted by another system with clock skew; timezone conversion mistakes making modified appear earlier than created; defaulting creationTime to DateTime.Now while restoring an old modified value.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/5e974ef55195bc20. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Annotations/Annotation.cs:140

        public Annotation(XmlQualifiedName annotationType, Guid id, DateTime creationTime, DateTime lastModificationTime)
        {
            ArgumentNullException.ThrowIfNull(annotationType);
            if (String.IsNullOrEmpty(annotationType.Name))
            {
                throw new ArgumentException(SR.TypeNameMustBeSpecified, "annotationType.Name");//needs better message
            }
            if (String.IsNullOrEmpty(annotationType.Namespace))
            {
                throw new ArgumentException(SR.TypeNameMustBeSpecified, "annotationType.Namespace");//needs better message
            }

            if (id.Equals(Guid.Empty))
            {
                throw new ArgumentException(SR.InvalidGuid, nameof(id));
            }
            if (lastModificationTime.CompareTo(creationTime) < 0)
            {
                throw new ArgumentException(SR.ModificationEarlierThanCreation, nameof(lastModificationTime));
            }
            _id = id;
            _typeName = annotationType;

            _created = creationTime;
            _modified = lastModificationTime;

            Init();
        }

        #endregion Constructors

        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

View on GitHub (pinned to 81131a70a4)