microsoft/aspire · error · InvalidOperationException

Volume source and target must be set

Error message

Volume source and target must be set

What it means

While converting the Aspire resource model to Docker Compose, ProcessVolumes iterates volume/bind-mount definitions and requires both Source and Target to be present. A mount missing either makes the compose volume entry undefined, so it throws InvalidOperationException. Docker Compose cannot express a named/bind volume without both sides.

Solutions

  1. Provide both source and target in the WithVolume/WithBindMount call, e.g. .WithBindMount("./data", "/app/data").
  2. If an anonymous volume was intended, use the API variant designed for that instead of passing null source.
  3. Inspect the resource whose mount is incomplete and fix the null argument at its definition site.

Example fix

// before
.WithBindMount(source: null, target: "/app/data")
// after
.WithBindMount(source: "./data", target: "/app/data");
Defensive patterns

Strategy: validation

Validate before calling

// before publish, assert all mounts are complete
foreach (var m in resource.Annotations.OfType<ContainerMountAnnotation>())
    if (m.Source is null || m.Target is null)
        throw new InvalidOperationException($"Resource {resource.Name} has a mount missing source or target");

Prevention

When it happens

Trigger: Publishing to a DockerComposeEnvironment when a resource has a volume/bind mount created with only one side set — e.g. builder.AddX(...).WithVolume(...) or WithBindMount where source path or container target path was passed as null.

Common situations: Anonymous-volume-style calls where developers passed null source expecting auto-generation; string interpolation producing empty/null paths; conditional code paths that skip setting the target.

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/3f3ae2c627f25e51. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Docker/DockerComposeEnvironmentContext.cs:81

                    endpoint.IsExternal,
                    endpoint.Name));
        }
    }

    private void ProcessVolumes(DockerComposeServiceResource serviceResource)
    {
        if (!serviceResource.TargetResource.TryGetContainerMounts(out var mounts))
        {
            return;
        }

        var bindMountIndex = 0;

        foreach (var mount in mounts)
        {
            if (mount.Source is null || mount.Target is null)
            {
                throw new InvalidOperationException("Volume source and target must be set");
            }

            var source = mount.Source;
            var name = mount.Source;

            // For bind mounts, create environment placeholders for the source path
            // Skip the docker socket which should be left as-is for portability
            if (mount.Type == ContainerMountType.BindMount && !IsDockerSocket(mount.Source))
            {
                // Create environment variable name: {RESOURCE_NAME}_BINDMOUNT_{INDEX}
                var envVarName = $"{serviceResource.Name.ToUpperInvariant().Replace("-", "_").Replace(".", "_")}_BINDMOUNT_{bindMountIndex}";
                bindMountIndex++;

                // Add the placeholder to captured environment variables so it gets written to the .env file
                // Use the original source path as the default value and pass the ContainerMountAnnotation as the source
                var placeholder = environment.AddEnvironmentVariable(
                    envVarName,
                    description: $"Bind mount source for {serviceResource.Name}:{mount.Target}",

View on GitHub (pinned to 25830f84bd)