netchx/netch · warning · UriFormatException

Text is not a URI

Error message

Text is not a URI

What it means

GetUriScheme extracts the scheme by locating the first '://' substring and taking everything before it; if '://' is absent it throws System.UriFormatException. It is used by ShareLink.ParseText to dispatch each line to the matching IServerUtil by URI scheme. So the error fires for any line passed into parsing that is not a well-formed scheme://rest URI.

Source

Thrown at Netch/Utils/ShareLink.cs:96

            var scheme = GetUriScheme(text);
            var util = ServerHelper.GetUtilByUriScheme(scheme);
            if (util != null)
                list.AddRange(util.ParseUri(text));
            else
                Log.Warning("\"{Scheme}\" scheme share link not supported", scheme);
        }

        foreach (var node in list.Where(node => !node.Remark.IsNullOrWhiteSpace()))
            node.Remark = RemoveEmoji(node.Remark);

        return list;
    }

    public static string GetUriScheme(string text)
    {
        var endIndex = text.IndexOf("://", StringComparison.Ordinal);
        if (endIndex == -1)
            throw new UriFormatException("Text is not a URI");

        return text.Substring(0, endIndex);
    }

    private static Server ParseNetchUri(string text)
    {
        text = URLSafeBase64Decode(text.Substring(8));

        var NetchLink = JsonSerializer.Deserialize<JsonElement>(text);

        if (string.IsNullOrEmpty(NetchLink.GetProperty("Hostname").GetString()))
            throw new FormatException();

        if (!ushort.TryParse(NetchLink.GetProperty("Port").GetString(), out _))
            throw new FormatException();

        return JsonSerializer.Deserialize<Server>(text,
            new JsonSerializerOptions

View on GitHub (pinned to 9d99eb1c5a)

Solutions

  1. Trim and skip blank lines before parsing.
  2. Validate each line with Uri.TryCreate or a '://' presence check and ignore invalid lines.
  3. If the source is a subscription, verify the URL returns plain-text links (HTTP 200, correct content-type).
  4. Use Uri.IsWellFormedOriginalString on trimmed input.

Example fix

// before
var endIndex = text.IndexOf("://", StringComparison.Ordinal);
if (endIndex == -1)
    throw new UriFormatException("Text is not a URI");
return text.Substring(0, endIndex);
// after - return null so batch callers can skip non-URI lines gracefully
public static string? GetUriScheme(string text)
{
    var endIndex = text.IndexOf("://", StringComparison.Ordinal);
    return endIndex == -1 ? null : text.Substring(0, endIndex);
}
Defensive patterns

Strategy: validation

Validate before calling

foreach (var raw in lines)
{
    var text = raw.Trim();
    if (text.Length == 0 || !text.Contains("://"))
    {
        Log.Debug("Skipping non-URI line: {Line}", text);
        continue;
    }
    var scheme = ShareLink.GetUriScheme(text);
    // ... dispatch
}

Type guard

static bool IsParsableUri(string text)
    => !string.IsNullOrWhiteSpace(text) && text.Contains("://") && Uri.TryCreate(text, UriKind.Absolute, out _);

Try / catch

try { scheme = ShareLink.GetUriScheme(text); }
catch (UriFormatException) { continue; /* skip non-URI lines */ }

Prevention

When it happens

Trigger: ParseText receives a line without '://': blank lines, stray text, comments, a bare hostname without scheme, or subscription content that is an error page / HTML rather than links.

Common situations: Pasting non-URI text into the 'add from URI' box; a subscription endpoint returning an error page or HTML; trailing whitespace/empty lines; a vmess:// link typo'd as vmess:/ .

Related errors


AI-assisted analysis of netchx/netch@9d99eb1c5a (2026-08-13). Data as JSON: /api/errors/ca0f7ffbed1ab136. Report an issue: GitHub.