{"record":{"id":"4468d8711ae4298b","repo":"PrismLibrary/Prism","slug":"the-constructed-uri-has-a-relative-back-operator-after-a-new","errorCode":null,"errorMessage":"The constructed URI has a relative back operator after a new Navigation Segment which is not supported - '{uri}'.","messagePattern":"The constructed URI has a relative back operator after a new Navigation Segment which is not supported - '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Maui/Prism.Maui/Navigation/Builder/NavigationBuilder.cs","lineNumber":118,"sourceCode":"\n    internal Uri BuildUri()\n    {\n        var uri = (_absoluteNavigation ? \"/\" : string.Empty) +\n            string.Join(\"/\", _uriSegments.Select(x => x.Segment));\n\n        if(uri.Contains(\"../\"))\n        {\n            if (_absoluteNavigation)\n                throw new InvalidOperationException(\"The generated URI has one or more relative back operators and was marked as an absolute path. This is not supported.\");\n\n            var segments = uri.Split('/');\n            if (!segments.Any(x => x != \"..\"))\n                throw new InvalidOperationException($\"The constructed URI contains one or more relative back operators, but contains no other navigation segments - '{uri}'.\");\n            var hasNonBackSegment = false;\n            for(int i = 0; i < segments.Length; i++)\n            {\n                if (hasNonBackSegment && segments[i] == \"..\")\n                    throw new InvalidOperationException($\"The constructed URI has a relative back operator after a new Navigation Segment which is not supported - '{uri}'.\");\n                else if (segments[i] != \"..\")\n                    hasNonBackSegment = true;\n            }\n        }\n\n        return UriParsingHelper.Parse(uri);\n    }\n}\n","sourceCodeStart":100,"sourceCodeEnd":127,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Maui/Prism.Maui/Navigation/Builder/NavigationBuilder.cs#L100-L127","documentation":"BuildUri also rejects a URI where a '..' back operator appears AFTER a real navigation segment, since .NET MAUI/Prism navigation cannot pop and then descend within a single URI in that order. It throws InvalidOperationException identifying the constructed URI.","triggerScenarios":"Building segments in the order [page segment, '..', ...] — e.g. AddSegment(\"DetailPage\").RelativeBack() — then calling NavigateAsync(); the loop detects hasNonBackSegment followed by a '..' segment.","commonSituations":"Misunderstanding that RelativeBack must precede new segments (it walks up first); assembling segments from user input or config in the wrong order; refactoring that appends a back step after navigating deeper.","solutions":["Reorder segments: put all RelativeBack() calls first, then the page segments to descend into: RelativeBack().AddSegment(\"DetailPage\").","Split navigation into two calls if you need pop-then-push semantics (GoBackAsync then NavigateAsync).","Validate the segment list before building: reject any '..' appearing after a non-'..' segment."],"exampleFix":"// before\nnavigationService.CreateBuilder().AddSegment(\"DetailPage\").RelativeBack().NavigateAsync(); // back after segment\n// after\nnavigationService.CreateBuilder().RelativeBack().AddSegment(\"DetailPage\").NavigateAsync(); // back first","handlingStrategy":"validation","validationCode":"bool backAfterSegment = false; bool hasPage = false;\nforeach (var s in segments)\n{\n    if (s == \"..\") { if (hasPage) { backAfterSegment = true; break; } }\n    else hasPage = true;\n}\nif (backAfterSegment) throw new InvalidOperationException(\"All '..' segments must precede page segments.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    await navigationService.NavigateAsync(uri);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"after a new Navigation Segment\"))\n{\n    logger.LogError(ex, \"Navigation segments out of order: {Uri}\", uri);\n}","preventionTips":["Always build URIs as [.. ']* followed by page segments.","Use RelativeBack() extension at the start of the chain, then AddSegment calls.","Split pop-then-push needs into GoBackAsync() + NavigateAsync() calls."],"tags":["navigation","uri","relative-back","segment-order"],"backgroundTag":"unsupported-operation","analyzedSha":"358118cd640d9a22ff8cf21c8ad197fa038b7990","analyzedAt":"2026-09-15T15:00:31.079Z","contentChangedAt":"2026-09-15T15:00:31.079Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}