AlexxIT/go2rtc · error

nest: wrong query

Error message

nest: wrong query

What it means

Dial in pkg/nest/client.go parses the connection DSN/query string and requires five parameters: client_id (cliendID), client_secret, refresh_token, project_id and device_id. If any of them is missing or empty it returns errors.New("nest: wrong query") without attempting any network connection. It is a fast-fail validation of the Nest connection configuration.

Solutions

  1. Print/log the query string (redacting secrets) and confirm all five keys exist and are non-empty: client_id, client_secret, refresh_token, project_id, device_id
  2. Fix key-name typos — parameters are read with query.Get so an unknown key silently yields ""
  3. Populate the missing credentials from Google Cloud / Nest Device Access console (OAuth client ID + secret) and from the SDM project/device
  4. Ensure env vars are actually exported in the runtime environment (container/systemd) before building the URL
  5. Add pre-dial validation in your own config loader that rejects an incomplete Nest config with a clearer message

Example fix

// before
u, _ := url.Parse(os.Getenv("NEST_URL")) // "nest:?project_id=x&device_id=y"
cli, err := nest.Dial(ctx, u)
// after
q := u.Query()
for _, k := range []string{"client_id", "client_secret", "refresh_token", "project_id", "device_id"} {
    if q.Get(k) == "" {
        return nil, fmt.Errorf("nest config missing %s", k)
    }
}
cli, err := nest.Dial(ctx, u)
Defensive patterns

Strategy: validation

Validate before calling

required := []string{"client_id", "client_secret", "refresh_token", "project_id", "device_id"}
q := u.Query()
for _, k := range required {
    if q.Get(k) == "" {
        return nil, fmt.Errorf("nest: query missing %q", k)
    }
}

Type guard

func hasAllNestParams(q url.Values) bool {
    for _, k := range []string{"client_id", "client_secret", "refresh_token", "project_id", "device_id"} {
        if q.Get(k) == "" { return false }
    }
    return true
}

Try / catch

cli, err := nest.Dial(ctx, u)
if err != nil {
    if err.Error() == "nest: wrong query" {
        return nil, fmt.Errorf("invalid NEST_URL: need client_id, client_secret, refresh_token, project_id, device_id")
    }
    return err
}

Prevention

When it happens

Trigger: Calling nest Dial with a query string (or option set) where one or more of client_id, client_secret, refresh_token, project_id or device_id is absent or empty — e.g. url "nest:?refresh_token=abc&project_id=p&device_id=d" (missing client_id/client_secret).

Common situations: Environment variables for Nest credentials not set so the DSN is built with empty values; query string typo'd key names (e.g. clientID instead of client_id); copying a device-only URL from the Nest Device Access console without the OAuth fields; missing device_id when only a project was configured.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/de39901773e38a11. Report an issue: GitHub.

Appendix: source

Thrown at pkg/nest/client.go:39

	conn *rtsp.Conn
	api  *API
}

func Dial(rawURL string) (core.Producer, error) {
	u, err := url.Parse(rawURL)
	if err != nil {
		return nil, err
	}

	query := u.Query()
	cliendID := query.Get("client_id")
	cliendSecret := query.Get("client_secret")
	refreshToken := query.Get("refresh_token")
	projectID := query.Get("project_id")
	deviceID := query.Get("device_id")

	if cliendID == "" || cliendSecret == "" || refreshToken == "" || projectID == "" || deviceID == "" {
		return nil, errors.New("nest: wrong query")
	}

	maxRetries := 3
	retryDelay := time.Second * 30

	var nestAPI *API
	var lastErr error

	for attempt := 0; attempt < maxRetries; attempt++ {
		nestAPI, err = NewAPI(cliendID, cliendSecret, refreshToken)
		if err == nil {
			break
		}
		lastErr = err
		if attempt < maxRetries-1 {
			time.Sleep(retryDelay)
			retryDelay *= 2 // exponential backoff
		}

View on GitHub (pinned to c245815e75)