microsoft/aspire · error · InvalidOperationException

Resource ' ' has a resource persistence mode but no source…

Error message

Resource '{resource.Name}' has a resource persistence mode but no source resource.

What it means

When a resource's PersistenceAnnotation uses PersistenceMode.Resource, its lifetime is inherited from the annotation's SourceResource. If SourceResource is null, the lifetime cannot be resolved, so GetLifetimeType throws InvalidOperationException.

Solutions

  1. Supply the source resource when using PersistenceMode.Resource (e.g. pass the resource to the persistence API).
  2. Use PersistenceMode.Session or PersistenceMode.Persistent if no source resource applies.
  3. Validate the annotation's SourceResource before publishing/starting the app model.

Example fix

// before
builder.AddRedis("cache").WithPersistence(PersistenceMode.Resource, source: null);
// after
var db = builder.AddPostgres("db");
builder.AddRedis("cache").WithPersistence(PersistenceMode.Resource, source: db);
Defensive patterns

Strategy: validation

Validate before calling

if (pa.Mode == PersistenceMode.Resource && pa.SourceResource is null) throw new InvalidOperationException("PersistenceMode.Resource requires a SourceResource");

Type guard

bool HasSource(PersistenceAnnotation pa) => pa.Mode != PersistenceMode.Resource || pa.SourceResource is not null;

Try / catch

try { var lifetime = resource.GetLifetimeType(); } catch (InvalidOperationException ex) when (ex.Message.Contains("no source resource")) { /* fix annotation, add source */ throw; }

Prevention

When it happens

Trigger: Creating a PersistenceAnnotation with Mode = PersistenceMode.Resource but without setting SourceResource (or passing null to the API), then resolving the resource lifetime.

Common situations: Manually constructing PersistenceAnnotation and forgetting the source; calling a persistence helper overload that omits the source resource while still requesting resource-persistence mode.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

        return GetLifetimeType(resource, []);
    }

    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;
    }

View on GitHub (pinned to 25830f84bd)