{"record":{"id":"16e954b66bc2848d","repo":"winsw/winsw","slug":"file-f-does-not-follow-the-pattern-provided","errorCode":null,"errorMessage":"File {f} does not follow the pattern provided","messagePattern":"File (.+?) does not follow the pattern provided","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/WinSW.Core/LogAppenders.cs","lineNumber":640,"sourceCode":"            else\n            {\n                foreach (string? f in files)\n                {\n                    try\n                    {\n                        string? filenameOnly = Path.GetFileNameWithoutExtension(f);\n                        int hashIndex = filenameOnly.IndexOf('#');\n                        string? lastNumberAsString = filenameOnly.Substring(hashIndex + 1, 4);\n                        if (int.TryParse(lastNumberAsString, out int lastNumber))\n                        {\n                            if (lastNumber > nextFileNumber)\n                            {\n                                nextFileNumber = lastNumber;\n                            }\n                        }\n                        else\n                        {\n                            throw new IOException($\"File {f} does not follow the pattern provided\");\n                        }\n                    }\n                    catch (Exception e)\n                    {\n                        throw new IOException($\"Failed to process file {f} due to error {e.Message}\", e);\n                    }\n                }\n\n                if (nextFileNumber == 0)\n                {\n                    throw new IOException(\"Cannot roll the file because matching pattern not found\");\n                }\n\n                nextFileNumber++;\n            }\n\n            return nextFileNumber;\n        }","sourceCodeStart":622,"sourceCodeEnd":658,"githubUrl":"https://github.com/winsw/winsw/blob/1d0ee4a91bad596d5e7e9c360f2b39ef54674674/src/WinSW.Core/LogAppenders.cs#L622-L658","documentation":"Thrown by RollingLogAppender.GetNextFileNumber during log file rotation when a file matching the glob pattern {baseFileName}.{datePattern}.#*{ext} is found, but the 4 characters after the '#' separator cannot be parsed as an integer. The appender expects a zero-padded sequence number in the #NNNN format to determine the next file number.","triggerScenarios":"GetNextFileNumber calls Directory.GetFiles with the glob, then for each file extracts filenameOnly.Substring(hashIndex + 1, 4) and runs int.TryParse. If those 4 characters are non-numeric the try-block throws this IOException. This happens when a file matches the glob (e.g., myservice.20240101.#abc.log) but the post-# segment is not a 4-digit number.","commonSituations":"A user or another process manually creates files in the log directory whose names match the glob but don't follow the #NNNN convention; leftover files from a different logging framework or an older WinSW pattern; a filename where '#' appears in an unexpected position causing the wrong 4 characters to be extracted.","solutions":["Remove or rename non-conforming files from the WinSW log directory","Ensure no other application writes files matching the {baseName}.{date}.#*{ext} glob into the log directory","If the log directory must be shared, configure a dedicated WinSW log subdirectory"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before rotation, scan the log directory for non-conforming files\nstring glob = $\"{baseFileName}.{now:yyyyMMdd}.#*{ext}\";\nforeach (var f in Directory.GetFiles(baseDirectory, glob))\n{\n    var name = Path.GetFileNameWithoutExtension(f);\n    int hash = name.IndexOf('#');\n    if (hash < 0 || hash + 4 >= name.Length || !int.TryParse(name.Substring(hash + 1, 4), out _))\n    {\n        Console.Error.WriteLine($\"Non-conforming log file will block rotation: {f}\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    int next = GetNextFileNumber(ext, baseDirectory, baseFileName, now);\n}\ncatch (IOException ex) when (ex.Message.Contains(\"does not follow the pattern\"))\n{\n    eventLogger.WriteEntry($\"Skipping rotation due to non-conforming log file: {ex.Message}\");\n}","preventionTips":["Keep the WinSW log directory exclusive to WinSW-managed files","Periodically clean up old or manually-created files in the log directory","Do not manually create files matching the {baseName}.{date}.#*{ext} glob pattern"],"tags":["logging","file-rotation","rolling","io"],"backgroundTag":null,"analyzedSha":"1d0ee4a91bad596d5e7e9c360f2b39ef54674674","analyzedAt":"2026-08-13T15:26:09.332Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}