GopeedLab/gopeed · error

webview rpc status %d

Error message

webview rpc status %d

What it means

The rpcprovider drives a webview over a local HTTP JSON-RPC endpoint, authenticating with a bearer token. This error means the POST completed but returned a status other than 200; the response body is closed without decoding, so details are lost. The RPC layer distinguishes transport errors (returned raw) from HTTP-level failures (this message) from in-band errors (body.Error).

Source

Thrown at internal/webview/rpcprovider/provider.go:178

	}

	req, err := http.NewRequest(http.MethodPost, c.endpoint, bytes.NewReader(payload))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	if c.token != "" {
		req.Header.Set("Authorization", "Bearer "+c.token)
	}

	resp, err := c.http.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("webview rpc status %d", resp.StatusCode)
	}

	var body enginewebview.RPCResponse
	if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
		return err
	}
	if body.Error != nil {
		return body.Error
	}
	if result == nil {
		return nil
	}
	if len(body.Result) == 0 || string(body.Result) == "null" {
		return nil
	}
	return json.Unmarshal(body.Result, result)
}

View on GitHub (pinned to 7b7327ffb3)

Solutions

  1. Check driver liveness first (process up, endpoint reachable)
  2. For 401/403: re-provision or re-read the token so client and driver agree
  3. For 404: align client and driver versions — a route mismatch usually means skew
  4. For 5xx: restart the driver, check its logs and memory

Example fix

// before
resp, err := c.call(ctx, method, params) // "webview rpc status 404" after upgrading the driver

// after
// re-sync endpoint + token from the driver, then retry once
if isRPCStatus(err) {
    c.RefreshEndpoint() // re-read base URL and token from driver state
    resp, err = c.call(ctx, method, params)
}
Defensive patterns

Strategy: retry

Validate before calling

// Health-check the RPC endpoint before a session of calls
func rpcHealthy(c *rpcClient, healthURL string) bool {
    resp, err := c.http.Get(healthURL)
    if err != nil {
        return false
    }
    defer resp.Body.Close()
    return resp.StatusCode == http.StatusOK
}

Try / catch

err := c.call(ctx, method, params)
if err != nil && strings.Contains(err.Error(), "webview rpc status ") {
    var code int
    fmt.Sscanf(err.Error(), "webview rpc status %d", &code)
    switch {
    case code == 401 || code == 403:
        return c.reauthAndRetry(ctx, method, params) // refresh token, retry once
    case code >= 500:
        return retryWithBackoff(func() error { return c.call(ctx, method, params) }, 2)
    }
    return err // 404 etc: version/route skew, needs operator action
}

Prevention

When it happens

Trigger: 401/403 when c.token is empty, stale, or rejected by the driver; 404 when the client's route does not match the driver version; 5xx when the driver process is crashing or out of resources. Any non-200 on the RPC endpoint.

Common situations: Driver and client version skew after an upgrade (route moved); token file regenerated but the client cached the old value; the webview driver process restarted or OOM-killed mid-session; port collision hitting a different local service.

Related errors


AI-assisted analysis of GopeedLab/gopeed@7b7327ffb3 (2026-08-16). Data as JSON: /api/errors/afbe0c6b4f4b8e9c. Report an issue: GitHub.