{"record":{"id":"e0e994bef9512602","repo":"OrchardCMS/OrchardCore","slug":"cannot-create-a-stream-for-a-directory","errorCode":null,"errorMessage":"Cannot create a stream for a directory.","messagePattern":"Cannot create a stream for a directory\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.Abstractions/Modules/FileProviders/EmbeddedDirectoryInfo.cs","lineNumber":54,"sourceCode":"\n    /// <summary>\n    /// The time when the directory was last written to.\n    /// </summary>\n    public DateTimeOffset LastModified => DateTimeOffset.MinValue;\n\n    /// <summary>\n    /// Always true.\n    /// </summary>\n    public bool IsDirectory => true;\n\n    /// <summary>\n    /// Always throws an exception because read streams are not support on directories.\n    /// </summary>\n    /// <exception cref=\"InvalidOperationException\">Always thrown.</exception>\n    /// <returns>Never returns.</returns>\n    public Stream CreateReadStream()\n    {\n        throw new InvalidOperationException(\"Cannot create a stream for a directory.\");\n    }\n}\n","sourceCodeStart":36,"sourceCodeEnd":57,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.Abstractions/Modules/FileProviders/EmbeddedDirectoryInfo.cs#L36-L57","documentation":"EmbeddedDirectoryInfo represents a directory entry in the embedded file provider; directories cannot be opened as streams. CreateReadStream always throws InvalidOperationException to enforce this contract, matching IFileInfo behavior for directories.","triggerScenarios":"Calling CreateReadStream() on an IFileInfo returned by the embedded/manifest embedded file provider when the requested path resolves to a directory (e.g. path 'MyFolder' without extension that exists as a folder in an embedded assembly), rather than a file.","commonSituations":"Enumerating embedded resources and blindly calling CreateReadStream on every entry, building a file-serving endpoint where the URL maps to a folder, or a path typo dropping the file name so the provider resolves the directory.","solutions":["Check IFileInfo.IsDirectory before calling CreateReadStream and skip or return a 404/handle directories.","Verify the embedded resource path points to an actual file; print available resources via the assembly manifest.","If the path may be a folder, append the expected file name or resolve the specific resource.","Wrap in try/catch InvalidOperationException only as a last resort; prefer the IsDirectory guard."],"exampleFix":"// before\nusing var stream = fileInfo.CreateReadStream();\n// after\nif (fileInfo.IsDirectory || !fileInfo.Exists)\n{\n    return Results.NotFound();\n}\nusing var stream = fileInfo.CreateReadStream();","handlingStrategy":"type-guard","validationCode":"if (fileInfo is { Exists: true, IsDirectory: false }) { /* safe to open stream */ }","typeGuard":"bool IsReadableFile(IFileInfo f) => f.Exists && !f.IsDirectory && f.Length >= 0;","tryCatchPattern":"try { using var s = fileInfo.CreateReadStream(); }\ncatch (InvalidOperationException) { return Results.NotFound(); }","preventionTips":["Always check IFileInfo.IsDirectory before CreateReadStream","Verify embedded resource names against the assembly manifest","Never build streams from path segments that may resolve to folders"],"tags":["file-provider","io","embedded-resources"],"backgroundTag":"path-is-not-a-directory","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"}