{"record":{"id":"d176e637106f66ce","repo":"microsoft/aspire","slug":"the-certificate-bundle-cache-file-prefix-contains-invalid","errorCode":null,"errorMessage":"The certificate bundle cache file prefix contains invalid characters.","messagePattern":"The certificate bundle cache file prefix contains invalid characters\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Projects/GuestAppHostProject.cs","lineNumber":2258,"sourceCode":"        string? devCertPemPath,\n        string environmentVariableName,\n        string cacheFilePrefix,\n        CancellationToken cancellationToken)\n    {\n        if (devCertPemPath is null)\n        {\n            return;\n        }\n\n        if (string.IsNullOrWhiteSpace(environmentVariableName))\n        {\n            throw new InvalidOperationException(\"The certificate bundle environment variable name cannot be empty.\");\n        }\n\n        if (string.IsNullOrWhiteSpace(cacheFilePrefix) ||\n            cacheFilePrefix.Any(character => !char.IsAsciiLetterOrDigit(character) && character is not '-' and not '_'))\n        {\n            throw new InvalidOperationException(\"The certificate bundle cache file prefix contains invalid characters.\");\n        }\n\n        // Explicit AppHost configuration takes precedence over the inherited environment.\n        // Environment variable names are case-insensitive on Windows.\n        var configuredKeys = _environment.IsWindows()\n            ? environmentVariables.Keys\n                .Where(key => string.Equals(key, environmentVariableName, StringComparison.OrdinalIgnoreCase))\n                .ToArray()\n            : environmentVariables.ContainsKey(environmentVariableName)\n                ? [environmentVariableName]\n                : [];\n        var existingCertificateBundle = configuredKeys.LastOrDefault() is { } configuredKey\n            ? environmentVariables[configuredKey]\n            : _environment.GetEnvironmentVariable(environmentVariableName);\n        var certificateBundlePath = devCertPemPath;\n\n        if (!string.IsNullOrWhiteSpace(existingCertificateBundle))\n        {","sourceCodeStart":2240,"sourceCodeEnd":2276,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Projects/GuestAppHostProject.cs#L2240-L2276","documentation":"The certificate bundle cache file prefix must contain only ASCII letters, digits, '-' or '_' because it is used to build cache file names. Passing a prefix that is empty, whitespace, or contains other characters throws InvalidOperationException.","triggerScenarios":"Constructing GuestAppHostProject with a cacheFilePrefix containing characters outside [A-Za-z0-9_-] (e.g. spaces, slashes, dots) or an empty/null prefix.","commonSituations":"Deriving the prefix from a package name, path segment, or version string that contains dots or slashes (e.g. 'My.App/1.0').","solutions":["Sanitize the prefix to ASCII letters, digits, '-', or '_' before passing it (e.g. replace invalid chars with '-')","Use a short alphanumeric identifier such as the app or component name","Check whether the value was assembled from a path or version and strip separators"],"exampleFix":"// before\nvar prefix = packageName + \"/\" + version; // contains '/'\n// after\nvar prefix = string.Concat(packageName, \"-\", version.Replace('.', '_'))\n    .Where(char.IsAsciiLetterOrDigit or '-' or '_');","handlingStrategy":"validation","validationCode":"var safePrefix = new string(prefix.Where(c => char.IsAsciiLetterOrDigit(c) || c is '-' or '_').ToArray());\nif (string.IsNullOrWhiteSpace(safePrefix)) throw new ArgumentException(\"cacheFilePrefix required\");","typeGuard":"bool IsValidCachePrefix(string? p) => !string.IsNullOrWhiteSpace(p) && p.All(c => char.IsAsciiLetterOrDigit(c) || c is '-' or '_');","tryCatchPattern":"try { var project = new GuestAppHostProject(..., cacheFilePrefix, ...); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"cache file prefix\"))\n{\n    prefix = SanitizePrefix(prefix);\n}","preventionTips":["Derive prefixes from names you control and sanitize separators (. / /) immediately","Test generated prefixes against [A-Za-z0-9_-] in unit tests","Keep prefixes short and alphanumeric by convention"],"tags":["csharp","configuration","validation","naming"],"backgroundTag":"invalid-argument-format","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"}