{"record":{"id":"ce74cfdbc56d98e0","repo":"felixse/FluentTerminal","slug":"invalid-link","errorCode":null,"errorMessage":"Invalid link.","messagePattern":"Invalid link\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"FluentTerminal.App/ViewModels/CommandProfileProviderViewModel.cs","lineNumber":432,"sourceCode":"\n            if (string.IsNullOrEmpty(queryString))\n            {\n                return vm;\n            }\n\n            if (queryString.StartsWith(\"?\", StringComparison.Ordinal))\n            {\n                queryString = queryString.Substring(1);\n            }\n\n            var queryStringParams = ParseParams(queryString, '&').ToList();\n\n            var cmdParam = queryStringParams.FirstOrDefault(t =>\n                CustomCommandQueryStringName.Equals(t.Item1, StringComparison.OrdinalIgnoreCase));\n\n            if (cmdParam == null)\n            {\n                throw new Exception(I18N.TranslateWithFallback(\"InvalidLink\", \"Invalid link.\"));\n            }\n\n            vm._command = cmdParam.Item2;\n\n            vm.LoadBaseFromQueryString(queryStringParams);\n\n            return vm;\n        }\n\n        public override async Task<Tuple<bool, string>> GetUrlAsync()\n        {\n            var error = await ValidateAsync().ConfigureAwait(false);\n\n            if (!string.IsNullOrEmpty(error))\n            {\n                return Tuple.Create(false, error);\n            }\n","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/felixse/FluentTerminal/blob/ba83ec485eea8d8ee65825711731300bee2e76ed/FluentTerminal.App/ViewModels/CommandProfileProviderViewModel.cs#L414-L450","documentation":"Thrown by CommandProfileProviderViewModel when the parsed query string contains no recognized custom-command parameter (CustomCommandQueryStringName). The provider builds a command-based profile from a URL; if the query lacks the expected 'command=...' key it cannot construct the profile and throws a generic Exception with the localized 'Invalid link.' text.","triggerScenarios":"ParseUrl/ParseQueryString processes a command-profile link whose query string is empty or contains only unrelated parameters; the cmdParam lookup via FirstOrDefault returns null, hitting the throw.","commonSituations":"User clicks/opens a malformed fluent-terminal:// link missing the command parameter; the link was hand-authored or truncated; a different provider's link is routed to the command provider by mistake.","solutions":["Ensure the link's query string includes the custom command parameter, e.g. ?command=ls%20-la.","Validate the URL scheme and required parameters in the caller before dispatching to this provider.","Catch the exception and show the user that the link is invalid rather than crashing."],"exampleFix":"// before\nvar cmdParam = queryStringParams.FirstOrDefault(t => CustomCommandQueryStringName.Equals(t.Item1, StringComparison.OrdinalIgnoreCase));\nif (cmdParam == null)\n    throw new Exception(I18N.TranslateWithFallback(\"InvalidLink\", \"Invalid link.\"));\n\n// after - throw a typed, parameterized exception\nif (cmdParam == null)\n    throw new ArgumentException($\"Invalid link: missing '{CustomCommandQueryStringName}' query parameter.\");","handlingStrategy":"validation","validationCode":"// Ensure the query carries the command parameter before dispatching.\nvar qs = System.Web.HttpUtility.ParseQueryString(uri.Query.TrimStart('?'));\nif (string.IsNullOrEmpty(qs[CustomCommandQueryStringName]))\n    throw new ArgumentException($\"Link missing '{CustomCommandQueryStringName}' parameter.\");","typeGuard":null,"tryCatchPattern":"try { vm = CommandProfileProviderViewModel.Parse(uri, ...); }\ncatch (Exception ex) when (ex.Message.Contains(\"Invalid link\")) { notifyUser(\"The link is not a valid command profile link.\"); }","preventionTips":["Validate the URL scheme and required query parameters before routing to the provider.","Author command links with the expected ?command=... parameter.","Catch and degrade gracefully on invalid links."],"tags":["uri-parsing","command-profile","input-validation","i18n"],"backgroundTag":null,"analyzedSha":"ba83ec485eea8d8ee65825711731300bee2e76ed","analyzedAt":"2026-08-13T21:23:15.467Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}