router-for-me/CLIProxyAPI · error

invalid source-url

Error message

invalid source-url

What it means

validateManifestSourceURL() url.Parse()s the trimmed source-url and requires both a scheme and a host. Parse failure, scheme-less ("github.com/acme/plug"), or host-less ("https:" alone) values are rejected as unparseable/unusable.

Source

Thrown at internal/pluginstore/manifest.go:184

func validateManifestPluginID(id string) error {
	id = strings.TrimSpace(id)
	if id == "" {
		return fmt.Errorf("missing required field id")
	}
	if !validPluginID(id) {
		return fmt.Errorf("invalid plugin id %q", id)
	}
	return nil
}

func validateManifestSourceURL(sourceURL string) error {
	sourceURL = strings.TrimSpace(sourceURL)
	if sourceURL == "" {
		return fmt.Errorf("missing required field source-url")
	}
	parsed, errParse := url.Parse(sourceURL)
	if errParse != nil || parsed.Scheme == "" || parsed.Host == "" {
		return fmt.Errorf("invalid source-url")
	}
	if parsed.Scheme != "https" && parsed.Scheme != "http" {
		return fmt.Errorf("source-url must use http or https")
	}
	if hasSensitiveQueryParameter(parsed) {
		return fmt.Errorf("source-url contains sensitive query parameter")
	}
	return nil
}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Write the full absolute URL including scheme and host: https://github.com/acme/plug
  2. Quote the value in YAML to avoid parser mangling
  3. Test the URL with url.Parse or by opening it in a browser before shipping

Example fix

# before
source-url: github.com/acme/plug
# invalid source-url

# after
source-url: https://github.com/acme/plug
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(strings.TrimSpace(m.SourceURL))
if err != nil || u.Scheme == "" || u.Host == "" {
    return errors.New("source-url must be an absolute URL with host")
}
_ = m.Validate()

Type guard

func absoluteSourceURL(raw string) bool { u, err := url.Parse(strings.TrimSpace(raw)); return err == nil && u.Scheme != "" && u.Host != "" }

Try / catch

if err := m.Validate(); err != nil && err.Error() == "invalid source-url" { /* prepend https:// if slug-like, re-validate */ }

Prevention

When it happens

Trigger: source-url: "github.com/acme/plug" (no scheme); "https:///path" (no host); any string net/url cannot parse (control chars, bad percent-encoding).

Common situations: Copying a bare repo slug instead of a URL; trailing configuration where the scheme got stripped; YAML quoting issues mangling the value (e.g. colon-space inside an unquoted scalar).

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/99f34a5149bcc0c0. Report an issue: GitHub.