{"record":{"id":"177a300f51d40f92","repo":"microsoft/aspire","slug":"value-has-already-been-set","errorCode":null,"errorMessage":"Value has already been set.","messagePattern":"Value has already been set\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Foundry/HostedAgent/AzureHostedAgentResource.cs","lineNumber":524,"sourceCode":"/// A static value provider that returns a fixed value once it's been set.\n/// </summary>\n\npublic class StaticValueProvider<T> : IValueProvider, IManifestExpressionProvider\n{\n    private T? _value;\n    private bool _isSet;\n\n    /// <inheritdoc/>\n    public string ValueExpression => \"{value}\";\n\n    /// <summary>\n    /// Sets the value of the provider.\n    /// </summary>\n    public void Set(T value)\n    {\n        if (_isSet)\n        {\n            throw new InvalidOperationException($\"Value has already been set.\");\n        }\n        _value = value;\n        _isSet = true;\n    }\n\n    /// <summary>\n    /// Creates a new instance of the <see cref=\"StaticValueProvider{T}\"/> class.\n    /// </summary>\n    public StaticValueProvider()\n    {\n        _isSet = false;\n    }\n\n    /// <summary>\n    /// Creates a new instance of the <see cref=\"StaticValueProvider{T}\"/> class.\n    /// </summary>\n    public StaticValueProvider(T value)\n    {","sourceCodeStart":506,"sourceCodeEnd":542,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Foundry/HostedAgent/AzureHostedAgentResource.cs#L506-L542","documentation":"This is a write-once guard on a value provider: Set(T) throws InvalidOperationException if the value has already been assigned. The Foundry hosted agent value providers are designed so each provider's value is set exactly once, typically during provisioning/configuration resolution.","triggerScenarios":"Calling Set twice on the same provider instance — e.g. reusing a provider across two provisioning runs, or calling Set explicitly after the framework already set the value.","commonSituations":"Unit tests setting a value then setting it again; app startup logic that re-runs configuration and re-invokes Set on a singleton provider; accidentally sharing one provider instance between two resources.","solutions":["Call Set at most once per provider instance","Create a new provider instance if you need to set a value again","Restructure code so the value is computed once before being assigned","In tests, use a fresh provider per test case"],"exampleFix":"// before\nvar provider = new HostedAgentValueProvider<string>();\nprovider.Set(\"a\");\nprovider.Set(\"b\"); // throws\n// after\nvar provider = new HostedAgentValueProvider<string>();\nprovider.Set(\"a\");\nvar provider2 = new HostedAgentValueProvider<string>();\nprovider2.Set(\"b\");","handlingStrategy":"try-catch","validationCode":"// No pre-check API exists; track assignment yourself\nbool assigned = false;\nvoid Assign(Provider p, string v) { if (assigned) throw new InvalidOperationException(\"Already assigned\"); p.Set(v); assigned = true; }","typeGuard":null,"tryCatchPattern":"try\n{\n    provider.Set(value);\n}\ncatch (InvalidOperationException ex) when (ex.Message == \"Value has already been set.\")\n{\n    logger.LogWarning(\"Provider value was set more than once; ignoring duplicate set.\");\n}","preventionTips":["Call Set exactly once per provider instance","Create a new provider instance for each configuration cycle","Avoid sharing provider instances across resources"],"tags":["azure","foundry","state","write-once"],"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-21T09:17:21.228Z"}