larksuite/cli · error

invalid %s %q: malformed URL

Error message

invalid %s %q: malformed URL

What it means

proxyURL failed to parse the configured proxy address with net/url.Parse. To avoid leaking credentials, the raw url.Parse error is deliberately not wrapped (it embeds the original URL, which may contain user:password); instead a generic 'malformed URL' message with a redacted address is returned.

Source

Thrown at internal/transport/config.go:198

	if b, err := strconv.ParseBool(s); err == nil {
		return b, nil
	}
	return false, fmt.Errorf("invalid %s %q (want true/false/1/0)", name, raw)
}

// proxyURL validates the fixed configured proxy configuration and returns its URL.
func (c *Config) proxyURL() (*url.URL, error) {
	raw := strings.TrimSpace(c.Proxy)
	if raw == "" {
		return nil, fmt.Errorf("%s is empty", envvars.CliProxyAddress)
	}
	redacted := redactProxyURL(raw)
	u, err := url.Parse(raw)
	if err != nil {
		// Do not wrap the raw url.Parse error: its string embeds the original
		// URL, which can contain userinfo (user:password). Return a redacted,
		// generic message instead.
		return nil, fmt.Errorf("invalid %s %q: malformed URL", envvars.CliProxyAddress, redacted)
	}
	if u.Scheme != "http" {
		return nil, fmt.Errorf("invalid %s %q: scheme must be http", envvars.CliProxyAddress, redacted)
	}
	if u.Host == "" {
		return nil, fmt.Errorf("invalid %s %q: missing host", envvars.CliProxyAddress, redacted)
	}
	// Security hardening: only allow a loopback proxy. This prevents accidental
	// cross-machine proxying of credentials/traffic.
	if u.Hostname() != "127.0.0.1" {
		return nil, fmt.Errorf("invalid %s %q: host must be 127.0.0.1", envvars.CliProxyAddress, redacted)
	}
	if u.Port() == "" {
		return nil, fmt.Errorf("invalid %s %q: explicit port is required", envvars.CliProxyAddress, redacted)
	}
	if u.Path != "" {
		return nil, fmt.Errorf("invalid %s %q: path is not allowed", envvars.CliProxyAddress, redacted)
	}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Print the value with delimiters to reveal hidden characters: `echo "[$LARKSUITE_CLI_PROXY_ADDRESS]"` (use `| cat -A` to see control chars).
  2. Set a clean, simple address: `export LARKSUITE_CLI_PROXY_ADDRESS=http://127.0.0.1:8080`.
  3. Remove any percent-escapes, control characters, or unexpanded template placeholders from the value.
  4. Re-export the variable in the current shell after fixing your profile; verify with `echo $LARKSUITE_CLI_PROXY_ADDRESS`.

Example fix

// before
export LARKSUITE_CLI_PROXY_ADDRESS=http://127.0.0.1:8080/%zz
// after
export LARKSUITE_CLI_PROXY_ADDRESS=http://127.0.0.1:8080
Defensive patterns

Strategy: validation

Validate before calling

addr="$LARKSUITE_CLI_PROXY_ADDRESS"
python3 -c "import sys,urllib.parse; urllib.parse.urlparse(sys.argv[1])" "$addr" || echo 'malformed proxy URL' >&2
# also spot control characters:
printf '%s' "$addr" | cat -A

Prevention

When it happens

Trigger: LARKSUITE_CLI_PROXY_ADDRESS set to something net/url cannot parse — e.g. control characters, invalid percent-escapes like `http://127.0.0.1:8080/%zz`, or malformed bracketed IPv6 hosts like `http://[::1:8080/` — while proxy mode is enabled.

Common situations: Typing the address by hand with a typo; shell interpolation inserting garbage (`http://$HOST:$PORT` with unset vars producing odd strings); pasting a URL containing invisible control characters; template expansion leaving placeholders like {{proxy_host}}.

Understand the failure class

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/ea295e296d8efe7a. Report an issue: GitHub.