{"record":{"id":"4b29e386b33e46d1","repo":"OrchardCMS/OrchardCore","slug":"failed-to-parse-smtp-pickup-directory-location-base-string","errorCode":null,"errorMessage":"Failed to parse SMTP pickup directory location base: {string.Join(System.Environment.NewLine, errors)}","messagePattern":"Failed to parse SMTP pickup directory location base: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore.Modules/OrchardCore.Email.Smtp/Services/SmtpPickupDirectoryResolver.cs","lineNumber":161,"sourceCode":"    private static bool IsWindowsDriveQualifiedPath(string pickupDirectoryLocation)\n        => pickupDirectoryLocation.Length >= 3 &&\n            char.IsAsciiLetter(pickupDirectoryLocation[0]) &&\n            pickupDirectoryLocation[1] == ':' &&\n            pickupDirectoryLocation[2] is '\\\\' or '/';\n\n    private static string NormalizeDirectorySeparators(string path)\n        => path?\n            .Replace('\\\\', Path.DirectorySeparatorChar)\n            .Replace('/', Path.DirectorySeparatorChar);\n\n    private static string ParseAndFormat(string template, FluidParser fluidParser, ShellOptions shellOptions, ShellSettings shellSettings)\n    {\n        var templateOptions = new TemplateOptions();\n        templateOptions.MemberAccessStrategy.Register<ShellSettings>();\n\n        if (!fluidParser.TryParse(template, out var parsedTemplate, out var errors))\n        {\n            throw new InvalidOperationException($\"Failed to parse SMTP pickup directory location base: {string.Join(System.Environment.NewLine, errors)}\");\n        }\n\n        var templateContext = new TemplateContext(templateOptions);\n        templateContext.SetValue(\"AppData\", shellOptions.ShellsApplicationDataPath);\n        templateContext.SetValue(\"ShellSettings\", shellSettings);\n\n        return parsedTemplate.Render(templateContext, NullEncoder.Default)\n            .ReplaceLineEndings(string.Empty)\n            .Trim();\n    }\n\n    private static bool IsWithinBasePath(string pickupDirectoryLocationBase, string pickupDirectoryLocation)\n    {\n        var relativePath = Path.GetRelativePath(pickupDirectoryLocationBase, pickupDirectoryLocation);\n\n        return relativePath == \".\" ||\n            (!relativePath.Equals(\"..\", StringComparison.Ordinal) &&\n             !relativePath.StartsWith($\"..{Path.DirectorySeparatorChar}\", StringComparison.Ordinal) &&","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.Email.Smtp/Services/SmtpPickupDirectoryResolver.cs#L143-L179","documentation":"The pickup directory base supports a Fluid template (with ShellSettings and AppData values). ParseAndFormat parses the template with FluidParser and throws InvalidOperationException when TryParse fails, joining the parser errors into the message. The configured template has invalid Fluid syntax.","triggerScenarios":"The pickup directory location base setting contains a malformed Liquid/Fluid template, e.g. unclosed {{ or {% tag, wrong filter syntax; ParseAndFormat runs while resolving the SMTP pickup directory.","commonSituations":"Admin hand-edits the base path and accidentally types '{{' or '{%' characters that are meaningful to Fluid (e.g. Windows paths or placeholders spelled incorrectly), causing the parser to reject it.","solutions":["Fix the Fluid template syntax in the pickup directory base setting (close all {{ }} and {% %} tags).","If you need literal braces, escape them rather than leaving raw '{{' or '{%' in the value.","Use only documented variables: {{ AppData }} and ShellSettings properties.","Validate the template with a Liquid parser/preview before saving the settings."],"exampleFix":"// before (unclosed tag)\n\"{{ ShellSettings.Name/Pickup\"\n// after\n\"{{ AppData }}/{{ ShellSettings.Name }}/Pickup\"","handlingStrategy":"validation","validationCode":"var parser = new FluidParser();\nif (!parser.TryParse(template, out _, out var errors))\n    throw new InvalidOperationException(\"Invalid Fluid template: \" + string.Join(Environment.NewLine, errors));","typeGuard":null,"tryCatchPattern":"try { var path = ParseAndFormat(template, ...); } catch (InvalidOperationException ex) when (ex.Message.StartsWith(\"Failed to parse SMTP pickup directory\")) { /* show parser errors in the settings UI */ }","preventionTips":["Test templates with a Liquid parser before saving.","Escape literal braces in paths rather than leaving raw '{{' or '{%'.","Use only the documented variables (AppData, ShellSettings)."],"tags":["email","smtp","fluid","template-syntax"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}