{"record":{"id":"b306e417c5b56cda","repo":"microsoft/aspire","slug":"aspireradius070","errorCode":"ASPIRERADIUS070","errorMessage":"Parameter '${userNameParameter.Name}' is used as both the user name and the password of '${resource.Name}'. Its Radius recipe generates a separate value for each, and a single parameter cannot be substituted for both, so consumers would receive the same value for both. Give the user name and the password their own parameters. Diagnostic: ASPIRERADIUS070.","messagePattern":"Parameter '(.+?)' is used as both the user name and the password of '(.+?)'\\. Its Radius recipe generates a separate value for each, and a single parameter cannot be substituted for both, so consumers would receive the same value for both\\. Give the user name and the password their own parameters\\. Diagnostic: ASPIRERADIUS070\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Radius/Publishing/RadiusInfrastructureBuilder.cs","lineNumber":2425,"sourceCode":"        // Applications.Datastores/mongoDatabases and Applications.Messaging/rabbitMQQueues types\n        // return only connectionString and password from listSecrets(), and expose the user the\n        // recipe created at properties.username.\n        //\n        // Known gap: this only works when the AppHost supplied a user-name *parameter*. The default\n        // user names (\"admin\" for MongoDB, \"guest\" for RabbitMQ) are appended through\n        // ReferenceExpressionBuilder.AppendFormatted(string?, string?), which formats immediately\n        // and writes the result into the format string, so they arrive here as opaque literal text\n        // with no value provider to substitute. Those connection strings keep the default user name.\n        if (schema.UserNameProperty is { } userNameProperty &&\n            TryGetCredentialParameter(withConnectionString, \"username\") is { } userNameParameter)\n        {\n            // Substitutions are keyed by parameter identity — that is all a value provider exposes\n            // when an env var is resolved — so one parameter cannot stand for two different\n            // recipe-generated values. Assigning both would silently keep only the later one and\n            // hand consumers `properties.username` where they asked for the password.\n            if (passwordParameter is not null && ReferenceEquals(passwordParameter, userNameParameter))\n            {\n                throw new InvalidOperationException(\n                    $\"Parameter '{userNameParameter.Name}' is used as both the user name and the password of \" +\n                    $\"'{resource.Name}'. Its Radius recipe generates a separate value for each, and a single parameter \" +\n                    $\"cannot be substituted for both, so consumers would receive the same value for both. Give the user \" +\n                    $\"name and the password their own parameters. Diagnostic: ASPIRERADIUS070.\");\n            }\n\n            WarnIfUserSuppliedCredentialIsReplaced(resource, userNameParameter, \"user name\");\n            RegisterRecipeCredential(userNameParameter, resource, isProjectionSubstitution: true);\n            _recipeSecretSubstitutions[userNameParameter] =\n                new ProjectedValue(construct, userNameProperty, IsSecret: false, IsNumeric: false);\n        }\n    }\n\n    /// <summary>\n    /// Wires a type whose <c>username</c>/<c>password</c> are required schema properties on the\n    /// resource: Aspire writes its own parameters there, so the deployed credentials are the ones\n    /// already composed into the connection string.\n    /// </summary>","sourceCodeStart":2407,"sourceCodeEnd":2443,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Radius/Publishing/RadiusInfrastructureBuilder.cs#L2407-L2443","documentation":"Thrown when the same parameter instance is supplied as both the user name and the password of a Radius-backed resource. Recipe substitutions are keyed by parameter identity, so one parameter cannot stand in for two different recipe-generated values; assigning both would silently keep only the later substitution and publish the username value where consumers asked for the password.","triggerScenarios":"Publishing a Radius resource where WithConnectionString/credential APIs (or ConfigureRadiusInfrastructure) received the identical IResourceBuilder parameter object for both userNameParameter and passwordParameter (checked via ReferenceEquals) in RadiusInfrastructureBuilder around line 2425.","commonSituations":"Reusing one builder.AddParameter result for both username and password arguments, e.g. builder.AddPostgres(...).WithUserName(param).WithPassword(param), or a helper method that caches a single parameter and passes it to both.","solutions":["Create a separate parameter for the password with builder.AddParameter and pass it to the password API instead of the username parameter","Give each credential its own name and value, e.g. var userParam = builder.AddParameter(\"db-user\"); var pwdParam = builder.AddParameter(\"db-pwd\");","If the values are genuinely identical, still use two distinct parameters so each substitution key is unique"],"exampleFix":"// before\nvar cred = builder.AddParameter(\"db-cred\", secret: true);\nvar db = builder.AddPostgres(\"pg\").WithUserName(cred).WithPassword(cred);\n// after\nvar user = builder.AddParameter(\"db-user\");\nvar pwd = builder.AddParameter(\"db-pwd\", secret: true);\nvar db = builder.AddPostgres(\"pg\").WithUserName(user).WithPassword(pwd);","handlingStrategy":"validation","validationCode":"var user = builder.AddParameter(\"db-user\");\nvar pwd = builder.AddParameter(\"db-pwd\", secret: true);\nif (ReferenceEquals(user.Resource, pwd.Resource))\n    throw new InvalidOperationException(\"username and password must be distinct parameters\");","typeGuard":"bool AreDistinctParameters(object a, object b) => !ReferenceEquals(a, b);","tryCatchPattern":null,"preventionTips":["Never reuse one AddParameter result for two different resource properties","Wrap credential wiring in helpers that always create two distinct parameters","Search the app model for shared credential variables passed to multiple APIs"],"tags":["radius","publishing","parameters","credentials"],"backgroundTag":"invalid-argument-value","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"}