git-ecosystem/git-credential-manager · error · ArgumentException
Not a valid URI
Error message
Not a valid URI: '{url}' What it means
The SessionManagerExtensions.OpenBrowser(string) overload parses the URL with Uri.TryCreate(UriKind.Absolute) and throws ArgumentException if the string is not an absolute URI, before handing it to the underlying session manager. It guards against launching a browser with a malformed or relative URL.
Solutions
- Ensure the URL string includes an absolute scheme, e.g. prefix with "https://" if missing
- Validate the URL with Uri.TryCreate(url, UriKind.Absolute, out _) before calling OpenBrowser
- Check where the URL originates (config, server response) — fix the producer sending a malformed/empty URL
- Use UriBuilder to construct the URL from host/path components instead of string concatenation
Example fix
// before
sm.OpenBrowser($"{host}/login/device"); // host lacks scheme -> throws
// after
var url = $"https://{host}/login/device";
if (Uri.TryCreate(url, UriKind.Absolute, out var _))
sm.OpenBrowser(url); Defensive patterns
Strategy: validation
Validate before calling
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri) ||
(uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps))
throw new ArgumentException($"Browser URL must be an absolute http(s) URI, got: '{url}'"); Type guard
bool IsAbsoluteHttpUrl(string s) => Uri.TryCreate(s, UriKind.Absolute, out var u) &&
(u.Scheme == Uri.UriSchemeHttp || u.Scheme == Uri.UriSchemeHttps); Try / catch
try
{
sm.OpenBrowser(url);
}
catch (ArgumentException ex) when (ex.Message.StartsWith("Not a valid URI"))
{
logger.LogError(ex, "Malformed browser URL: {Url}", url);
} Prevention
- Always include the scheme (https://) when building URLs for browser opening
- Validate with Uri.TryCreate(UriKind.Absolute) before any browser launch
- Prefer UriBuilder over string concatenation for constructing URLs
When it happens
Trigger: Calling sm.OpenBrowser(url) with a string that is not an absolute URI — empty string, relative path like "/login", missing scheme like "example.com/auth", or a URL with invalid characters.
Common situations: Building OAuth/browser authentication URLs with string concatenation that omits the https:// scheme, capturing a truncated URL from logs, or passing a null/empty value from configuration.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Argument must be an absolute URI.
- Must specify at least one AuthenticationModes
- Argument cannot be empty or white space.
- Argument must be positive or zero (non-negative).
- Argument must be positive.
AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11).
Data as JSON: /api/errors/39019c1d8aa04f2f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Core/ISessionManager.cs:34
/// </summary>
/// <returns>True if the session can display a web browser, false otherwise.</returns>
bool IsWebBrowserAvailable { get; }
/// <summary>
/// Open the system web browser to the specified URL.
/// </summary>
/// <param name="uri"><see cref="Uri"/> to open the browser at.</param>
/// <exception cref="InvalidOperationException">Thrown if <see cref="IsWebBrowserAvailable"/> is false.</exception>
void OpenBrowser(Uri uri);
}
public static class SessionManagerExtensions
{
public static void OpenBrowser(this ISessionManager sm, string url)
{
if (!Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
{
throw new ArgumentException($"Not a valid URI: '{url}'");
}
sm.OpenBrowser(uri);
}
}
public abstract class SessionManager : ISessionManager
{
protected ITrace Trace { get; }
protected IEnvironment Environment { get; }
protected IFileSystem FileSystem { get; }
protected SessionManager(ITrace trace, IEnvironment env, IFileSystem fs)
{
EnsureArgument.NotNull(trace, nameof(trace));
EnsureArgument.NotNull(env, nameof(env));
EnsureArgument.NotNull(fs, nameof(fs));
View on GitHub (pinned to e8ce762cd0)