{"record":{"id":"0eb57e4e5f6d11a9","repo":"microsoft/aspire","slug":"azure-sandbox-endpoint-endpointreferenceexpression-endpoint","errorCode":null,"errorMessage":"Azure sandbox endpoint '{_endpointReferenceExpression.Endpoint.EndpointName}' on resource '{_resource.TargetResource.Name}' does not have a deployed URL yet. Runtime sandbox URLs cannot be used as first-pass Azure provisioning values; deploy the producing sandbox before resolving this reference.","messagePattern":"Azure sandbox endpoint '(.+?)' on resource '(.+?)' does not have a deployed URL yet\\. Runtime sandbox URLs cannot be used as first-pass Azure provisioning values; deploy the producing sandbox before resolving this reference\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxEndpointPropertyValueProvider.cs","lineNumber":50,"sourceCode":"        if (endpointReferenceExpression.Property == EndpointProperty.TargetPort)\n        {\n            _targetPort = ResolveEndpointTargetPort(resource, endpointReferenceExpression.Endpoint.EndpointName) ??\n                throw new InvalidOperationException($\"Endpoint '{endpointReferenceExpression.Endpoint.EndpointName}' on resource '{resource.TargetResource.Name}' does not have a target port.\");\n        }\n        else\n        {\n            var sandboxEndpoint = ResolveSandboxEndpoint(resource, endpointReferenceExpression.Endpoint);\n            _sandboxEndpoint = sandboxEndpoint;\n            _targetPort = sandboxEndpoint.TargetPort;\n        }\n    }\n\n    public string ValueExpression =>\n        $\"{{{_resource.Name}.endpoints.{_endpointReferenceExpression.Endpoint.EndpointName}.{_endpointReferenceExpression.Property.ToString().ToLowerInvariant()}}}\";\n\n    public ValueTask<string?> GetValueAsync(CancellationToken cancellationToken = default)\n    {\n        return new(GetKnownValueWithoutDeploymentState() ?? throw CreateUnresolvedEndpointException());\n    }\n\n    public async ValueTask<string?> GetValueAsync(ValueProviderContext context, CancellationToken cancellationToken = default)\n    {\n        if (GetKnownValueWithoutDeploymentState() is { } knownValue)\n        {\n            return knownValue;\n        }\n\n        if (context.ExecutionContext is null)\n        {\n            throw CreateUnresolvedEndpointException();\n        }\n\n        var deploymentStateManager = context.ExecutionContext.Services.GetRequiredService<IDeploymentStateManager>();\n        var stateSection = await deploymentStateManager\n            .AcquireSectionAsync(AzureSandboxContainerDeployment.GetStateSectionName(_resource), cancellationToken)\n            .ConfigureAwait(false);","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxEndpointPropertyValueProvider.cs#L32-L68","documentation":"AzureSandboxEndpointPropertyValueProvider resolves sandbox endpoint URLs, but during first-pass Azure provisioning a runtime sandbox URL does not exist yet. When no known static value is available, the provider throws, explaining that runtime sandbox URLs cannot be used as first-pass provisioning values. The producing sandbox must be deployed before this reference can resolve.","triggerScenarios":"Calling the parameterless-context GetValueAsync(CancellationToken) when GetKnownValueWithoutDeploymentState() returns null; e.g. an endpoint reference to another sandbox resource's endpoint evaluated outside a deployment-state-aware context.","commonSituations":"Referencing a sandbox resource's endpoint from another resource's config during provision/publish before the sandbox was ever deployed; provisioning with no saved deployment state; wiring consumers to sandbox endpoints at first-pass evaluation.","solutions":["Deploy the producing sandbox first so a deployed URL exists, then re-run the resolution.","Provide a known static value via configuration so GetKnownValueWithoutDeploymentState() returns it.","Use the ValueProviderContext overload during provisioning so deployment state can be consulted.","Add an explicit dependency (WaitFor) on the sandbox resource so evaluation happens after deployment."],"exampleFix":"// before: reading the sandbox URL during first-pass provisioning\nvar url = await provider.GetValueAsync(ct); // throws: no deployed URL yet\n// after: ensure the consumer depends on the sandbox\nmyResource.WaitFor(sandboxResource); // reference resolves only after deployment produces a URL","handlingStrategy":"fallback","validationCode":"// before referencing, check whether a known/static value exists\nif (!config.HasKey($\"{resourceName}:endpoints:{endpointName}:url\"))\n{\n    // schedule the sandbox deployment first instead of resolving now\n}","typeGuard":"static bool HasDeployedUrl(AzureSandboxEndpointPropertyValueProvider provider) =>\n    provider.ValueExpression is { } expr && ConfigContainsKey(expr); // known value check","tryCatchPattern":"try\n{\n    url = await provider.GetValueAsync(cancellationToken);\n}\ncatch (UnresolvedEndpointException)\n{\n    // fallback: trigger sandbox deployment, then retry resolution\n    await DeploySandboxAsync(targetResource);\n    url = await provider.GetValueAsync(cancellationToken);\n}","preventionTips":["Add WaitFor/dependency edges so the producing sandbox deploys before consumers resolve its endpoints.","Do not evaluate sandbox endpoint references during publish/manifest generation.","Keep deployment state files present when provisioning incrementally.","Provide static config overrides when a URL is known outside the deployment pipeline."],"tags":["azure","sandbox","endpoint","provisioning"],"backgroundTag":"invalid-state-transition","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}