{"record":{"id":"de39901773e38a11","repo":"AlexxIT/go2rtc","slug":"nest-wrong-query","errorCode":null,"errorMessage":"nest: wrong query","messagePattern":"nest: wrong query","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/nest/client.go","lineNumber":39,"sourceCode":"\tconn *rtsp.Conn\n\tapi  *API\n}\n\nfunc Dial(rawURL string) (core.Producer, error) {\n\tu, err := url.Parse(rawURL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tquery := u.Query()\n\tcliendID := query.Get(\"client_id\")\n\tcliendSecret := query.Get(\"client_secret\")\n\trefreshToken := query.Get(\"refresh_token\")\n\tprojectID := query.Get(\"project_id\")\n\tdeviceID := query.Get(\"device_id\")\n\n\tif cliendID == \"\" || cliendSecret == \"\" || refreshToken == \"\" || projectID == \"\" || deviceID == \"\" {\n\t\treturn nil, errors.New(\"nest: wrong query\")\n\t}\n\n\tmaxRetries := 3\n\tretryDelay := time.Second * 30\n\n\tvar nestAPI *API\n\tvar lastErr error\n\n\tfor attempt := 0; attempt < maxRetries; attempt++ {\n\t\tnestAPI, err = NewAPI(cliendID, cliendSecret, refreshToken)\n\t\tif err == nil {\n\t\t\tbreak\n\t\t}\n\t\tlastErr = err\n\t\tif attempt < maxRetries-1 {\n\t\t\ttime.Sleep(retryDelay)\n\t\t\tretryDelay *= 2 // exponential backoff\n\t\t}","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/nest/client.go#L21-L57","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["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","Fix key-name typos — parameters are read with query.Get so an unknown key silently yields \"\"","Populate the missing credentials from Google Cloud / Nest Device Access console (OAuth client ID + secret) and from the SDM project/device","Ensure env vars are actually exported in the runtime environment (container/systemd) before building the URL","Add pre-dial validation in your own config loader that rejects an incomplete Nest config with a clearer message"],"exampleFix":"// before\nu, _ := url.Parse(os.Getenv(\"NEST_URL\")) // \"nest:?project_id=x&device_id=y\"\ncli, err := nest.Dial(ctx, u)\n// after\nq := u.Query()\nfor _, k := range []string{\"client_id\", \"client_secret\", \"refresh_token\", \"project_id\", \"device_id\"} {\n    if q.Get(k) == \"\" {\n        return nil, fmt.Errorf(\"nest config missing %s\", k)\n    }\n}\ncli, err := nest.Dial(ctx, u)","handlingStrategy":"validation","validationCode":"required := []string{\"client_id\", \"client_secret\", \"refresh_token\", \"project_id\", \"device_id\"}\nq := u.Query()\nfor _, k := range required {\n    if q.Get(k) == \"\" {\n        return nil, fmt.Errorf(\"nest: query missing %q\", k)\n    }\n}","typeGuard":"func hasAllNestParams(q url.Values) bool {\n    for _, k := range []string{\"client_id\", \"client_secret\", \"refresh_token\", \"project_id\", \"device_id\"} {\n        if q.Get(k) == \"\" { return false }\n    }\n    return true\n}","tryCatchPattern":"cli, err := nest.Dial(ctx, u)\nif err != nil {\n    if err.Error() == \"nest: wrong query\" {\n        return nil, fmt.Errorf(\"invalid NEST_URL: need client_id, client_secret, refresh_token, project_id, device_id\")\n    }\n    return err\n}","preventionTips":["Build the Nest DSN from a validated config struct, never from raw string concatenation of env vars","Fail fast at application startup by dialing Nest once and surfacing config errors early","Use exactly the key names the library reads: client_id, client_secret, refresh_token, project_id, device_id","Keep credentials in one secrets store and verify all five fields exist before writing the URL"],"tags":["nest","configuration","validation","query-string"],"backgroundTag":"missing-required-config-field","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}