microsoft/aspire · error · InvalidOperationException

Unknown persistence mode

Error message

Unknown persistence mode '{Enum.GetName(typeof(PersistenceMode), persistenceAnnotation.Mode)}'.

What it means

GetLifetimeType maps each PersistenceMode enum value to a Lifetime. If the annotation's Mode is not one of the known values (Session, Persistent, Resource, ParentProcess), the switch's default arm throws InvalidOperationException naming the unknown mode.

Solutions

  1. Upgrade all Aspire packages to the same version so PersistenceMode values align.
  2. Avoid casting raw ints to PersistenceMode; use the enum members.
  3. Inspect the annotation that carries the bad mode and correct it to a valid enum member.

Example fix

// before
annotation.Mode = (PersistenceMode)99; // invalid
// after
annotation.Mode = PersistenceMode.Persistent; // valid enum member
Defensive patterns

Strategy: try-catch

Validate before calling

if (!Enum.IsDefined(typeof(PersistenceMode), pa.Mode)) throw new InvalidOperationException($"Unknown PersistenceMode: {pa.Mode}");

Type guard

bool IsKnown(PersistenceMode m) => Enum.IsDefined(typeof(PersistenceMode), m);

Try / catch

try { var lifetime = resource.GetLifetimeType(); } catch (InvalidOperationException ex) when (ex.Message.Contains("Unknown persistence mode")) { /* check package version alignment */ throw; }

Prevention

When it happens

Trigger: A PersistenceAnnotation with an out-of-range or unrecognized PersistenceMode value — typically from a newer/older assembly mismatch where an enum value was added but this switch predates it, or from manual annotation construction with a cast int.

Common situations: Version skew between Aspire packages where one package writes a PersistenceMode value the hosting core doesn't know; unsafe casts like (PersistenceMode)42 in custom tooling.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/a635f52b121f14bb. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs:1130

    private static Lifetime GetLifetimeType(IResource resource, HashSet<IResource> visitedResources)
    {
        if (!visitedResources.Add(resource))
        {
            throw new InvalidOperationException($"A circular lifetime reference was detected for resource '{resource.Name}'.");
        }

        if (resource.TryGetLastAnnotation<PersistenceAnnotation>(out var persistenceAnnotation))
        {
            return persistenceAnnotation.Mode switch
            {
                PersistenceMode.Session => Lifetime.Session,
                PersistenceMode.Persistent => Lifetime.Persistent,
                PersistenceMode.Resource => persistenceAnnotation.SourceResource is { } sourceResource
                    ? GetLifetimeType(sourceResource, visitedResources)
                    : throw new InvalidOperationException($"Resource '{resource.Name}' has a resource persistence mode but no source resource."),
                PersistenceMode.ParentProcess => Lifetime.Persistent,
                _ => throw new InvalidOperationException($"Unknown persistence mode '{Enum.GetName(typeof(PersistenceMode), persistenceAnnotation.Mode)}'.")
            };
        }

        if (resource.TryGetLastAnnotation<ContainerLifetimeAnnotation>(out var containerLifetimeAnnotation))
        {
            return containerLifetimeAnnotation.Lifetime switch
            {
                ContainerLifetime.Session => Lifetime.Session,
                ContainerLifetime.Persistent => Lifetime.Persistent,
                _ => throw new InvalidOperationException($"Unknown container lifetime '{Enum.GetName(typeof(ContainerLifetime), containerLifetimeAnnotation.Lifetime)}'.")
            };
        }

        return Lifetime.Session;
    }

    /// <summary>
    /// Determines whether the specified resource has a persistent lifetime.

View on GitHub (pinned to 25830f84bd)