{"record":{"id":"c71f1fda64c222e6","repo":"microsoft/aspire","slug":"unknown-typeof-t-name-value-value-valid-values-are-string","errorCode":null,"errorMessage":"Unknown {typeof(T).Name} value \"{value}\". Valid values are {string.Join(\", \", Enum.GetNames(typeof(T)))}.","messagePattern":"Unknown (.+?) value \"(.+?)\"\\. Valid values are (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Shared/IConfigurationExtensions.cs","lineNumber":202,"sourceCode":"    /// <param name=\"defaultValue\">A default value, for when the configuration value is unable to be parsed.</param>\n    /// <exception cref=\"InvalidOperationException\">The configuration value is not a valid member of the enum.</exception>\n    /// <returns>The parsed enum member, or <paramref name=\"defaultValue\"/> the configuration value was null or empty.</returns>\n    [return: NotNullIfNotNull(nameof(defaultValue))]\n    public static T? GetEnum<T>(this IConfiguration configuration, string key, T? defaultValue = default)\n        where T : struct\n    {\n        var value = configuration[key];\n\n        if (value is null or [])\n        {\n            return defaultValue;\n        }\n        else if (Enum.TryParse<T>(value, ignoreCase: true, out var e))\n        {\n            return e;\n        }\n\n        throw new InvalidOperationException($\"Unknown {typeof(T).Name} value \\\"{value}\\\". Valid values are {string.Join(\", \", Enum.GetNames(typeof(T)))}.\");\n    }\n\n    /// <summary>\n    /// Gets the specified required configuration value as a member of an enum.\n    /// </summary>\n    /// <remarks>\n    /// Parsing is case-insensitive.\n    /// </remarks>\n    /// <param name=\"configuration\">The <see cref=\"IConfiguration\"/> this method extends.</param>\n    /// <param name=\"key\">The configuration key.</param>\n    /// <exception cref=\"InvalidOperationException\">The configuration value is empty or not a valid member of the enum.</exception>\n    /// <returns>The parsed enum member.</returns>\n    public static T GetEnum<T>(this IConfiguration configuration, string key)\n        where T : struct\n    {\n        var value = configuration.GetEnum<T>(key, defaultValue: null);\n\n        if (value is null)","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Shared/IConfigurationExtensions.cs#L184-L220","documentation":"IConfigurationExtensions.GetEnum<T> parses a configuration value into enum type T case-insensitively and throws InvalidOperationException listing the valid enum names when the value does not match any member. The message includes the type name, offending value, and the valid alternatives.","triggerScenarios":"Calling GetEnum<T>(configuration, key) where the key's value is a non-empty string that is not a valid T member — e.g. a typo, a different casing convention with added characters, a numeric string not corresponding to a defined name parse, or a value written for a different enum type.","commonSituations":"Config value changed between app versions after enum members were renamed; user hand-edited appsettings with an unsupported word like 'Default ' (trailing space works via parse? — trailing whitespace causes failure); value copied from documentation of another library's enum.","solutions":["Set the config value to one of the names listed in the exception message (case-insensitive)","Use Enum.TryParse or Enum.IsDefined on the raw value before calling GetEnum to validate","Check for typos or stray whitespace in the configuration value","Confirm the value was not written for a different enum type than the generic parameter T","If enum members were renamed in a newer version, migrate the stored config value accordingly"],"exampleFix":"// before\n// DASHBOARD_MODE=Prodcution   (typo)\nvar mode = configuration.GetEnum<DashboardMode>(\"DASHBOARD_MODE\"); // throws\n// after\n// DASHBOARD_MODE=Production\nvar mode = configuration.GetEnum<DashboardMode>(\"DASHBOARD_MODE\");\n// or defensively:\nvar raw = configuration[\"DASHBOARD_MODE\"];\nvar mode = Enum.TryParse<DashboardMode>(raw, ignoreCase: true, out var m)\n    ? m\n    : DashboardMode.Production; // fallback default","handlingStrategy":"validation","validationCode":"var raw = configuration[key];\nif (!Enum.TryParse<T>(raw, ignoreCase: true, out var parsed))\n    throw new InvalidOperationException($\"'{key}' must be one of: {string.Join(\", \", Enum.GetNames(typeof<T>))}.\");","typeGuard":"static bool IsValidEnumValue<T>(string? raw) where T : struct, Enum =>\n    Enum.TryParse<T>(raw, ignoreCase: true, out _);","tryCatchPattern":"try { return configuration.GetEnum<T>(key); }\ncatch (InvalidOperationException ex) { logger.LogError(ex, \"Unknown value for '{Key}'; using default\", key); return defaultEnumValue; }","preventionTips":["Copy enum names exactly from the exception's valid-values list","Validate config enums at startup, not deep in request paths","Trim whitespace from hand-edited appsettings values","Update stored config when enum members are renamed between versions"],"tags":["configuration","enum","parsing","invalid-enum"],"backgroundTag":"invalid-enum-value","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"}