HMCL-dev/HMCL · error · JsonParseException

Invalid URL:

Error message

Invalid URL: 

What it means

TerracottaNode.validate parses the node's url string with java.net.URI to confirm it is syntactically valid; a URISyntaxException is rethrown as JsonParseException. The guard runs during JSON validation so malformed node URLs fail fast at config load.

Solutions

  1. Fix the url string to a valid RFC 2396 URI (include scheme, percent-encode special characters)
  2. Trim whitespace and illegal characters from the url
  3. Validate with new URI(candidate) locally before saving the config
  4. Catch JsonParseException in the loader and reject/repair the offending node entry

Example fix

// before
"url": "my terracotta node:8080"
// after
"url": "https://my-terracotta-node:8080"
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(url, "url"); new URI(url.trim());

Type guard

static boolean validUrl(String url) { if (url == null || url.isBlank()) return false; try { new URI(url.trim()); return true; } catch (URISyntaxException e) { return false; } }

Try / catch

try { node.validate(); } catch (JsonParseException e) { LOG.warning("Rejecting malformed node URL", e); }

Prevention

When it happens

Trigger: A terracotta node entry whose url string cannot be parsed by new URI(url) — missing scheme, illegal characters, spaces, unmatched brackets in host, etc.

Common situations: Hand-editing the terracotta node list; copying URLs with trailing whitespace or unencoded characters; forgetting the scheme (e.g. 'localhost:8080').

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/8a6bac00ae25f276. Report an issue: GitHub.

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNodeList.java:48

import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

import static org.jackhuang.hmcl.util.logging.Logger.LOG;

/// @author Glavo
public final class TerracottaNodeList {
    private static final String NODE_LIST_URL = "https://terracotta.glavo.site/nodes";

    @JsonSerializable
    private record TerracottaNode(String url, @Nullable String region) implements Validation {
        @Override
        public void validate() throws JsonParseException, TolerableValidationException {
            Validation.requireNonNull(url, "TerracottaNode.url cannot be null");
            try {
                new URI(url);
            } catch (URISyntaxException e) {
                throw new JsonParseException("Invalid URL: " + url, e);
            }
        }
    }

    private static volatile List<URI> list;

    public static List<URI> fetch() {
        List<URI> list = TerracottaNodeList.list;
        if (list != null)
            return list;

        synchronized (TerracottaNodeList.class) {
            list = TerracottaNodeList.list;
            if (list != null)
                return list;

            try {
                List<TerracottaNode> nodes = HttpRequest.GET(NODE_LIST_URL)

View on GitHub (pinned to 24702dc5a0)