microsoft/aspire · error · ArgumentException
The API key parameter must be marked as secret. Use…
Error message
The API key parameter must be marked as secret. Use AddParameter with secret: true when creating the parameter.
What it means
WithApiKey validates that the IResourceBuilder<IResourceWithParameter> passed as apiKey was created as a secret parameter (parameter resource's Secret flag). Passing a non-secret parameter would cause the API key to be emitted as plain configuration instead of a secret, so the method throws ArgumentException immediately. This is an explicit API contract check.
Solutions
- Change the parameter creation to builder.AddParameter("my-key", secret: true) before passing it to WithApiKey.
- Verify the resource passed to WithApiKey is the parameter resource, not another resource.
- If the parameter is shared, create a dedicated secret parameter for the API key.
Example fix
// before
var key = builder.AddParameter("openai-key");
var openai = builder.AddOpenAI("openai").WithApiKey(key);
// after
var key = builder.AddParameter("openai-key", secret: true);
var openai = builder.AddOpenAI("openai").WithApiKey(key); Defensive patterns
Strategy: type-guard
Type guard
bool IsValidApiKeyParameter(IResourceBuilder<IResourceWithParameter> b) => b.Resource is IResourceWithParameter { } r &&
((IValueProvider)r is { } || true) && GetSecretFlag(r);
// simplest: check before calling
// if (!apiKey.Resource.Secret) throw before invoking WithApiKey Try / catch
try { openai.WithApiKey(apiKey); } catch (ArgumentException ex) { /* re-create parameter with secret: true */ } Prevention
- Always create API key parameters with AddParameter(name, secret: true)
- Centralize secret-parameter creation in a helper to avoid drift
- Review parameter declarations when sharing them between resources
When it happens
Trigger: Calling openai.WithApiKey(builder.AddParameter("my-key")) (secret defaults to false) or WithApiKey over a parameter created by another library call that did not pass secret: true.
Common situations: Copying a parameter declaration from non-secret examples; sharing a parameter between a secret and non-secret consumer; refactoring where secret: true was dropped.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- adminPassword
- OpenAI API key parameter
- A circular lifetime reference was detected for resource
- A global MCP approval policy cannot be combined with custom…
- A security rule named
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/00e4ce3bc2edce3f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.OpenAI/OpenAIExtensions.cs:167
ArgumentNullException.ThrowIfNull(builder);
ArgumentException.ThrowIfNullOrEmpty(endpoint);
builder.Resource.Endpoint = endpoint;
return builder;
}
/// <summary>
/// Configures the API key for the OpenAI parent resource from a parameter.
/// </summary>
[AspireExport]
public static IResourceBuilder<OpenAIResource> WithApiKey(this IResourceBuilder<OpenAIResource> builder, IResourceBuilder<ParameterResource> apiKey)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(apiKey);
if (!apiKey.Resource.Secret)
{
throw new ArgumentException("The API key parameter must be marked as secret. Use AddParameter with secret: true when creating the parameter.", nameof(apiKey));
}
// Remove the existing parameter if it's the default one
if (builder.Resource.DefaultKeyParameter == builder.Resource.Key)
{
builder.ApplicationBuilder.Resources.Remove(builder.Resource.Key);
}
builder.Resource.Key = apiKey.Resource;
return builder;
}
/// <summary>
/// Adds a health check to the OpenAI Model resource.
/// </summary>
/// <param name="builder">The resource builder.</param>
/// <returns>The resource builder.</returns>View on GitHub (pinned to 25830f84bd)