felixse/FluentTerminal · error · FormatException

UserInfo part contains ${parts.Length} elements.

Error message

UserInfo part contains ${parts.Length} elements.

What it means

Same FormatException as the App.ViewModels copy: SshConnectViewModel.ParseUri splits uri.UserInfo on ';' and requires at most two parts (username; optional options). More than two segments is treated as a malformed SSH/Mosh URI. This instance lives under the FluentTerminal.App project layout.

Source

Thrown at FluentTerminal.App/ViewModels/Profiles/SshConnectViewModel.cs:404

            IApplicationView applicationView, ITrayProcessCommunicationService trayProcessCommunicationService,
            IFileSystemService fileSystemService, IApplicationDataContainer historyContainer)
        {
            var vm = new SshConnectViewModel(settingsService, applicationView, trayProcessCommunicationService,
                fileSystemService)
            {
                Host = uri.Host,
                UseMosh = MoshUriScheme.Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase)
            };

            if (uri.Port >= 0)
                vm.SshPort = (ushort)uri.Port;

            if (!string.IsNullOrEmpty(uri.UserInfo))
            {
                string[] parts = uri.UserInfo.Split(';');

                if (parts.Length > 2)
                    throw new FormatException($"UserInfo part contains {parts.Length} elements.");

                vm.Username = HttpUtility.UrlDecode(parts[0]);

                if (parts.Length > 1)
                {
                    // For now we are only interested in IdentityFile option
                    Tuple<string, string> identityFileOption = ParseParams(parts[1], ',').FirstOrDefault(p =>
                        string.Equals(p.Item1, IdentityFileOptionName, StringComparison.OrdinalIgnoreCase));

                    vm.IdentityFile = identityFileOption?.Item2;
                }
            }

            // ReSharper disable once ConstantConditionalAccessQualifier
            string queryString = uri.Query?.Trim();

            if (string.IsNullOrEmpty(queryString))
            {

View on GitHub (pinned to ba83ec485e)

Solutions

  1. Encode ';' characters in UserInfo values as %3B, or keep UserInfo to a single username plus at most one options segment.
  2. Validate the URI shape before invoking ParseUri and surface a clear error.
  3. Use the documented format ssh://user;IdentityFile=<path>@host.

Example fix

// before
if (parts.Length > 2)
    throw new FormatException($"UserInfo part contains {parts.Length} elements.");

// after - clearer, structured message
if (parts.Length > 2)
    throw new FormatException($"SSH UserInfo has {parts.Length} segments; expected 'user' or 'user;options'.");
Defensive patterns

Strategy: validation

Validate before calling

if (!string.IsNullOrEmpty(uri.UserInfo) && uri.UserInfo.Split(';').Length > 2)
    throw new FormatException($"SSH UserInfo has too many segments.");

Type guard

static bool IsValidSshUserInfo(Uri uri) => string.IsNullOrEmpty(uri.UserInfo) || uri.UserInfo.Split(';').Length <= 2;

Try / catch

try { vm = SshConnectViewModel.ParseUri(uri, ...); }
catch (FormatException ex) { notifyUser($"Invalid SSH link: {ex.Message}"); }

Prevention

When it happens

Trigger: ParseUri receives an ssh:// or mosh:// URI whose UserInfo has three or more ';'-delimited segments. The guard fires before username/options are read.

Common situations: Malformed pasted SSH URL; unencoded ';' inside a username or IdentityFile value; a config generator emitted extra segments; wrong provider routed to SSH parser.

Related errors


AI-assisted analysis of felixse/FluentTerminal@ba83ec485e (2026-08-13). Data as JSON: /api/errors/b6c1f29bd46d80fa. Report an issue: GitHub.