microsoft/aspire · error · ArgumentException
Manifest field dictionaries must use string keys.
Error message
Manifest field dictionaries must use string keys.
What it means
Dictionaries passed as manifest field values must have string keys because JSON objects only support string keys. When an IDictionary entry's key is not a string (e.g. int, enum, or a custom key type), the normalizer throws this ArgumentException (note: without a parameter name).
Solutions
- Convert the dictionary to Dictionary<string, object?> with keys serialized via ToString() before passing
- Use StringEnumConverters or map enum keys to their string names explicitly
- For numeric keys, prefix/convert them to strings (e.g. key.ToString(CultureInfo.InvariantCulture))
Example fix
// before
var replicas = new Dictionary<WorkloadKind, int> { [WorkloadKind.Web] = 3 };
manifest.WithField("spec.replicasByKind", replicas);
// after
var replicas = new Dictionary<string, object?> { [WorkloadKind.Web.ToString()] = 3 };
manifest.WithField("spec.replicasByKind", replicas); Defensive patterns
Strategy: validation
Validate before calling
bool allStringKeys = dict is IDictionary d && d.Keys.Cast<object>().All(k => k is string);
Type guard
static bool HasStringKeys(IDictionary d) => d.Keys.Cast<object>().All(k => k is string);
Try / catch
try { manifest.WithField(path, dict); } catch (ArgumentException ex) when (ex.Message.Contains("string keys")) { var fixedDict = dict.Keys.Cast<object>().ToDictionary(k => k.ToString()!, k => dict[k]); manifest.WithField(path, fixedDict); } Prevention
- Always build manifest dictionaries as Dictionary<string, object?>
- Convert enum or numeric keys to strings before adding
- Avoid Hashtable for manifest fields
When it happens
Trigger: Calling WithField with a Dictionary<int, ...>, Dictionary<MyEnum, ...>, Hashtable, or any IDictionary whose keys are not strings. Also occurs when passing a dictionary that got boxed into IDictionary with non-string keys at runtime.
Common situations: Using enums as lookup keys, building maps from parsed data with numeric keys, or passing a Hashtable copied from legacy code. Developers expect keys to be auto-stringified, but the library requires explicit strings.
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
- Manifest field numeric values must be finite.
- Unsupported JSON value kind
- Cannot set nested manifest field
- Expected a non-empty Kubernetes MicroTime value.
- Expected a string token for Kubernetes MicroTime but found
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/a865c14bb2beac8a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Kubernetes/KubernetesManifestResource.cs:243
JsonValueKind.True => true,
JsonValueKind.False => false,
JsonValueKind.Number when element.TryGetInt64(out var longValue) => longValue,
JsonValueKind.Number => element.GetDouble(),
JsonValueKind.Array => element.EnumerateArray().Select(NormalizeJsonElement).ToList(),
JsonValueKind.Object => element.EnumerateObject().ToDictionary(prop => prop.Name, prop => NormalizeJsonElement(prop.Value), StringComparer.Ordinal),
_ => throw new ArgumentException($"Unsupported JSON value kind '{element.ValueKind}'.", nameof(element))
};
}
private static Dictionary<string, object?> NormalizeDictionary(IDictionary dictionary)
{
var result = new Dictionary<string, object?>(StringComparer.Ordinal);
foreach (DictionaryEntry entry in dictionary)
{
if (entry.Key is not string key)
{
throw new ArgumentException("Manifest field dictionaries must use string keys.");
}
result[key] = NormalizeManifestValue(entry.Value);
}
return result;
}
private static List<object?> NormalizeEnumerable(IEnumerable enumerable)
{
var result = new List<object?>();
foreach (var item in enumerable)
{
result.Add(NormalizeManifestValue(item));
}
return result;View on GitHub (pinned to 25830f84bd)