dotnet/aspnetcore · error · ArgumentException

There is already a persisted object under the same key '{key

Error message

There is already a persisted object under the same key '{key}'

What it means

PersistAsJson throws ArgumentException when _currentState.TryAdd(key, ...) returns false, i.e. a value already exists under the same key. PersistentComponentState does not overwrite, so duplicate keys during one persist cycle are treated as a programming error.

Source

Thrown at src/Components/Components/src/PersistentComponentState.cs:120

    /// <summary>
    /// Serializes <paramref name="instance"/> as JSON and persists it under the given <paramref name="key"/>.
    /// </summary>
    /// <typeparam name="TValue">The <paramref name="instance"/> type.</typeparam>
    /// <param name="key">The key to use to persist the state.</param>
    /// <param name="instance">The instance to persist.</param>
    [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
    public void PersistAsJson<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string key, TValue instance)
    {
        ArgumentNullException.ThrowIfNull(key);

        if (!PersistingState)
        {
            throw new InvalidOperationException("Persisting state is only allowed during an OnPersisting callback.");
        }

        if (!_currentState.TryAdd(key, JsonSerializer.SerializeToUtf8Bytes(instance, JsonSerializerOptionsProvider.Options)))
        {
            throw new ArgumentException($"There is already a persisted object under the same key '{key}'");
        }
    }

    [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
    internal void PersistAsJson(string key, object instance, [DynamicallyAccessedMembers(JsonSerialized)] Type type)
    {
        ArgumentNullException.ThrowIfNull(key);

        if (!PersistingState)
        {
            throw new InvalidOperationException("Persisting state is only allowed during an OnPersisting callback.");
        }

        if (!_currentState.TryAdd(key, JsonSerializer.SerializeToUtf8Bytes(instance, type, JsonSerializerOptionsProvider.Options)))
        {
            throw new ArgumentException($"There is already a persisted object under the same key '{key}'");
        }
    }

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Use a unique key per component/service (prefix with the component name or a GUID).
  2. Track which keys have been persisted and skip duplicates, or only persist from a single owner.
  3. If overwriting is desired, design your own state bag instead of relying on PersistAsJson.

Example fix

// before
State.PersistAsJson("state", a);
State.PersistAsJson("state", b); // duplicate -> throws

// after
State.PersistAsJson("componentA.state", a);
State.PersistAsJson("componentB.state", b);
Defensive patterns

Strategy: validation

Validate before calling

static readonly HashSet<string> _persistedKeys = new();
void PersistUnique(string key, object value)
{
    if (!_persistedKeys.Add(key)) return; // or throw/log
    State.PersistAsJson(key, value);
}

Try / catch

try { State.PersistAsJson(key, value); }
catch (ArgumentException ex) when (ex.Message.Contains("already a persisted object"))
{ logger.LogWarning(ex, "Duplicate persist key {Key}", key); }

Prevention

When it happens

Trigger: Two components or services persisting under the same key in the same cycle; calling PersistAsJson twice with the same key; key naming collisions across feature modules.

Common situations: Generic key names like "state" or "data" reused across components; multiple instances of the same component persisting; copy-paste of persistence code without unique keys.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/4723e02a9df0abb3. Report an issue: GitHub.