Summary
When browsing a content collection in the portal, clicking a file or folder whose name contains a space (or any other character the browser percent-encodes) produces a "not found" error. The collection browser lists such items correctly, but opening them fails.
How to reproduce
- On any node that has a content collection (for example the default
content collection), add a file whose name contains a space, such as my report.md. A folder with a space in its name, such as Data Extraction, reproduces the same way.
- Open the collection browser in the portal at
/{node}/content. The item my report.md (or the Data Extraction folder) is listed correctly, with its space intact.
- Click the item. The browser navigates to
/{node}/content/my%20report.md (the space percent-encoded as %20).
- Observe the error instead of the file content or folder listing.
Actual behavior
The page renders:
'my%20report.md' not found in collection 'content'.
Note the literal %20 in the message — the encoded form is compared directly against the collection's real item names.
Expected behavior
The file renders (or the folder opens) as it does for items whose names contain no encoded characters. Percent-encoded URL segments are decoded before they are matched against the collection's stored item names.
Root cause
The content-collection layout areas take the path from the raw URL id (host.Reference.Id) and use it as a collection path without URL-decoding it. The stored item name contains a real space (my report.md), while the path from the URL contains my%20report.md, so the case-insensitive equality match never succeeds and the fallback "not found" branch is returned.
The only decodes in the resolution chain are WorkspaceReference.Decode (which reverses the custom %9Y→. escaping, not percent-encoding) and query-string parsing — neither touches %20 in the path. The shared file renderer ContentLayoutArea.RenderFile re-encodes the path with Uri.EscapeDataString when it builds the static URL, which confirms the internal contract expects an already-decoded path; the callers violate that contract.
This is not related to nesting depth. It occurs whenever any path segment contains a character the browser percent-encodes; names without such characters resolve correctly, which is why most navigation works.
Affected code
src/MeshWeaver.ContentCollections/CollectionNamedLayoutArea.cs — RenderCore, where path is derived from host.Reference.Id and matched against item.Path.
src/MeshWeaver.ContentCollections/ContentLayoutArea.cs — UnifiedContentCore, which reads host.Reference.Id raw for the unified $Content path.
Suggested fix
URL-decode each path segment (Uri.UnescapeDataString, splitting on / first so separators are preserved) at both boundaries where the URL id becomes a content-collection path, before it is matched against the provider's item names.
Summary
When browsing a content collection in the portal, clicking a file or folder whose name contains a space (or any other character the browser percent-encodes) produces a "not found" error. The collection browser lists such items correctly, but opening them fails.
How to reproduce
contentcollection), add a file whose name contains a space, such asmy report.md. A folder with a space in its name, such asData Extraction, reproduces the same way./{node}/content. The itemmy report.md(or theData Extractionfolder) is listed correctly, with its space intact./{node}/content/my%20report.md(the space percent-encoded as%20).Actual behavior
The page renders:
Note the literal
%20in the message — the encoded form is compared directly against the collection's real item names.Expected behavior
The file renders (or the folder opens) as it does for items whose names contain no encoded characters. Percent-encoded URL segments are decoded before they are matched against the collection's stored item names.
Root cause
The content-collection layout areas take the path from the raw URL id (
host.Reference.Id) and use it as a collection path without URL-decoding it. The stored item name contains a real space (my report.md), while the path from the URL containsmy%20report.md, so the case-insensitive equality match never succeeds and the fallback "not found" branch is returned.The only decodes in the resolution chain are
WorkspaceReference.Decode(which reverses the custom%9Y→.escaping, not percent-encoding) and query-string parsing — neither touches%20in the path. The shared file rendererContentLayoutArea.RenderFilere-encodes the path withUri.EscapeDataStringwhen it builds the static URL, which confirms the internal contract expects an already-decoded path; the callers violate that contract.This is not related to nesting depth. It occurs whenever any path segment contains a character the browser percent-encodes; names without such characters resolve correctly, which is why most navigation works.
Affected code
src/MeshWeaver.ContentCollections/CollectionNamedLayoutArea.cs—RenderCore, wherepathis derived fromhost.Reference.Idand matched againstitem.Path.src/MeshWeaver.ContentCollections/ContentLayoutArea.cs—UnifiedContentCore, which readshost.Reference.Idraw for the unified$Contentpath.Suggested fix
URL-decode each path segment (
Uri.UnescapeDataString, splitting on/first so separators are preserved) at both boundaries where the URL id becomes a content-collection path, before it is matched against the provider's item names.