JamesNK/Newtonsoft.Json · error · InvalidOperationException

Cannot change schema while validating JSON.

Error message

Cannot change schema while validating JSON.

What it means

Thrown by the JsonValidatingReader.Schema setter when the schema is changed after validation has started (i.e. TokenType is no longer JsonToken.None). Changing the schema mid-stream would invalidate the in-progress validation state (scopes, current model), so it is rejected with InvalidOperationException. The schema must be set before any Read() call.

Source

Thrown at Src/Newtonsoft.Json/JsonValidatingReader.cs:311

        public JsonValidatingReader(JsonReader reader)
        {
            ValidationUtils.ArgumentNotNull(reader, nameof(reader));
            _reader = reader;
            _stack = new Stack<SchemaScope>();
        }

        /// <summary>
        /// Gets or sets the schema.
        /// </summary>
        /// <value>The schema.</value>
        public JsonSchema Schema
        {
            get => _schema;
            set
            {
                if (TokenType != JsonToken.None)
                {
                    throw new InvalidOperationException("Cannot change schema while validating JSON.");
                }

                _schema = value;
                _model = null;
            }
        }

        /// <summary>
        /// Gets the <see cref="JsonReader"/> used to construct this <see cref="JsonValidatingReader"/>.
        /// </summary>
        /// <value>The <see cref="JsonReader"/> specified in the constructor.</value>
        public JsonReader Reader => _reader;

        /// <summary>
        /// Changes the reader's state to <see cref="JsonReader.State.Closed"/>.
        /// If <see cref="JsonReader.CloseInput"/> is set to <c>true</c>, the underlying <see cref="JsonReader"/> is also closed.
        /// </summary>
        public override void Close()

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Set Schema immediately after constructing JsonValidatingReader, before calling Read().
  2. Pass the schema via the JsonValidatingReader(JsonReader, JsonSchema) constructor to enforce ordering.
  3. Create a fresh JsonValidatingReader per schema rather than mutating an active one.

Example fix

// before
var validating = new JsonValidatingReader(textReader);
while (validating.Read()) { /* ... */ }
validating.Schema = otherSchema; // throws

// after
var validating = new JsonValidatingReader(textReader, otherSchema);
Defensive patterns

Strategy: validation

Validate before calling

if (validating.TokenType == JsonToken.None)
{
    validating.Schema = schema;
}

Type guard

static bool CanSetSchema(JsonValidatingReader r) => r.TokenType == JsonToken.None;

Prevention

When it happens

Trigger: Assigning reader.Schema = newSchema after at least one Read() has advanced the token past None; reassigning the schema per-iteration inside a read loop.

Common situations: Building the validating reader, reading a few tokens, then assigning the schema; lazy/deferred schema loading that assigns after first read; copying/reusing a reader instance for multiple schemas without recreating it.

Related errors


AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07). Data as JSON: /api/errors/09bd056b91a32ed1. Report an issue: GitHub.