jstedfast/MailKit · error · InvalidOperationException
Cannot create child folders.
Error message
Cannot create child folders.
What it means
This InvalidOperationException is thrown by QueueCreateCommand when attempting to create a child folder under a parent whose DirectorySeparator is '\0' - meaning the server (or this folder) does not support a hierarchy separator, so child folders cannot exist under it.
Solutions
- Ensure the parent folder's children were loaded (folder.Open + get subfolders) so DirectorySeparator is known before creating children.
- Create the folder with its full hierarchical path from the top-level (root) folder instead of nesting: root.CreateFolder("Parent/Child") with the correct separator.
- Check folder.DirectorySeparator before attempting nested creation and fall back to flat names if '\0'.
- Some servers (or folder objects not opened as selectable) never expose a separator; verify server hierarchy support (LIST "" "%%").
Example fix
// before
var parent = client.GetFolder("Parent");
parent.CreateFolder("Child"); // throws if separator unknown
// after
var parent = client.GetFolder("Parent");
if (parent.DirectorySeparator == '\0')
client.GetFolder(Cancellation).CreateFolder("Parent" + sep + "Child");
else
parent.CreateFolder("Child"); Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrEmpty(folder.FullName) || folder.DirectorySeparator != '\0') { folder.CreateFolder(name); } else { /* create via full path from root */ } Try / catch
try { parent.CreateFolder(name); } catch (InvalidOperationException) { root.CreateFolder(parent.FullName + sep + name); } Prevention
- Check DirectorySeparator before creating children under a non-root folder.
- Open/initialize the parent folder (children loaded) before child creation.
- Prefer creating folders by full path from the root folder for predictable behavior.
- Verify server hierarchy support with LIST "" "%%" when in doubt.
When it happens
Trigger: Calling childFolder.CreateFolder(name) where childFolder has a non-empty FullName but DirectorySeparator == '\0' - typical when the folder was opened without its children (children collection not loaded) or the server reports no separator for that mailbox.
Common situations: Creating subfolders under a folder whose separator is unknown because the folder was never opened/its children not initialized; servers that report no hierarchy delimiter for that mailbox; using a stale folder reference where DirectorySeparator was never populated.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- An ImapFolder has not been opened.
- Annotation attribute specifiers cannot be empty.
- Annotation attribute specifiers cannot contain '*' or '%'.
- Annotation entry paths cannot be empty.
- Annotation entry paths must begin with '/'.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/045a11057c086b98.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Imap/ImapFolder.cs:838
Engine.OnFolderCreated (folder);
}
return folder;
}
ImapCommand QueueCreateCommand (string name, bool isMessageFolder, CancellationToken cancellationToken, out string encodedName)
{
if (name == null)
throw new ArgumentNullException (nameof (name));
if (!ImapEngine.IsValidMailboxName (name, DirectorySeparator))
throw new ArgumentException ("The name is not a legal folder name.", nameof (name));
CheckState (false, false);
if (!string.IsNullOrEmpty (FullName) && DirectorySeparator == '\0')
throw new InvalidOperationException ("Cannot create child folders.");
var fullName = !string.IsNullOrEmpty (FullName) ? FullName + DirectorySeparator + name : name;
encodedName = Engine.EncodeMailboxName (fullName);
var createName = encodedName;
if (!isMessageFolder && Engine.QuirksMode != ImapQuirksMode.GMail)
createName += DirectorySeparator;
return Engine.QueueCommand (cancellationToken, null, "CREATE %S\r\n", createName);
}
MailboxIdResponseCode? ProcessCreateResponse (ImapCommand ic)
{
ProcessResponseCodes (ic, null);
if (ic.Response != ImapCommandResponse.Ok && ic.GetResponseCode (ImapResponseCodeType.AlreadyExists) == null)
throw ImapCommandException.Create ("CREATE", ic);
View on GitHub (pinned to 9d3859a785)