siyuan-note/siyuan · error

missing query param [u]

Error message

missing query param [u]

What it means

parseForwardProxyParams handles SiYuan's forward-proxy endpoint. The target URL must be supplied as query param `u`, base64 (RawURLEncoding) encoded. When `u` is absent or empty the handler aborts with "missing query param [u]" before doing any network work.

Solutions

  1. Add the `u` query parameter containing base64.RawURLEncoding of the target URL string
  2. Ensure the value is RawURLEncoding (no padding, - and _ alphabet), not StdEncoding
  3. Reproduce the encoding the frontend uses (search forwardProxy in app/src) and mirror it in your client

Example fix

// before
fetch("/api/network/forwardProxy?url=https://example.com")
// after
const u = base64urlEncode("https://example.com");
fetch("/api/network/forwardProxy?u=" + u)
Defensive patterns

Strategy: validation

Validate before calling

if (!params.u) throw new Error("forwardProxy requires the u query param (base64url of target URL)");

Try / catch

try {
  await fetch("/api/network/forwardProxy?" + qs);
} catch (e) {
  if (String(e.msg).includes("missing query param")) fixParamEncoding();
}

Prevention

When it happens

Trigger: Calling a forward-proxy API route (e.g. /api/network/forwardProxy) without the `u` query parameter, or with `u=` empty.

Common situations: Hand-constructed curl/browser requests to the proxy endpoint; a client integration that forgot to encode the target URL; older plugin code written against a changed API surface.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/0f5786cfe8559a36. Report an issue: GitHub.

Appendix: source

Thrown at kernel/api/network.go:338

	dialer := util.SSRFSafeDialer(timeout)

	client := req.C()
	client.SetTimeout(timeout)
	client.SetDial(dialer.DialContext)
	client.SetRedirectPolicy(req.MaxRedirectPolicy(3))
	return client
}

// parseForwardProxyParams decodes the `u` and `h` query parameters.
//
// Query params:
//   - `u`: RawURLEncoding base64 of the target URL string.
//   - `h`: RawURLEncoding base64 of a JSON object map[string][]string.
//   - `timeout`: The timeout for the request in nanoseconds.
func parseForwardProxyParams(c *gin.Context) (parsedURL *url.URL, headers *http.Header, timeout time.Duration, err error) {
	uParam := c.Query("u")
	if uParam == "" {
		err = fmt.Errorf("missing query param [u]")
		return
	}
	uBytes, decErr := base64.RawURLEncoding.DecodeString(uParam)
	if decErr != nil {
		err = fmt.Errorf("decode [u] failed: %s", decErr.Error())
		return
	}
	parsedURL, err = url.ParseRequestURI(string(uBytes))
	if err != nil {
		err = fmt.Errorf("parse [u] failed: %s", err.Error())
		return
	}

	h := http.Header{}
	headers = &h
	hParam := c.Query("h")
	if hParam != "" {
		hBytes, decErr := base64.RawURLEncoding.DecodeString(hParam)

View on GitHub (pinned to 9f775e8a12)