{"record":{"id":"bb300d324765ea95","repo":"AlexxIT/go2rtc","slug":"wrong-pin-code","errorCode":null,"errorMessage":"wrong pin code","messagePattern":"wrong pin code","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/roborock/client.go","lineNumber":211,"sourceCode":"\t\t\tif !ok {\n\t\t\t\treturn errors.New(\"can't connect\")\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}\n\t}\n}\n\nfunc (c *Client) CheckHomesecPassword() (err error) {\n\tvar ok bool\n\n\tparams := `{\"password\":\"` + c.pin + `\"}`\n\tif err = c.iot.Call(\"check_homesec_password\", params, &ok); err != nil {\n\t\treturn\n\t}\n\n\tif !ok {\n\t\treturn errors.New(\"wrong pin code\")\n\t}\n\n\treturn nil\n}\n\nfunc (c *Client) GetHomesecConnectStatus() (clientID string, err error) {\n\tvar res []byte\n\n\tif err = c.iot.Call(\"get_homesec_connect_status\", nil, &res); err != nil {\n\t\treturn\n\t}\n\n\tvar v struct {\n\t\tStatus   int    `json:\"status\"`\n\t\tClientID string `json:\"client_id\"`\n\t}\n\tif err = json.Unmarshal(res, &v); err != nil {\n\t\treturn","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/roborock/client.go#L193-L229","documentation":"Roborock homesec guard: the IoT RPC 'check_homesec_password' succeeded but returned ok=false, meaning the configured pin does not match the device's home-security password. Pure credential rejection — the device rejected the pin supplied on the client.","triggerScenarios":"Calling CheckHomesecPassword (via Dial) with a Client whose `pin` does not match the device's home-security PIN — wrong PIN typed, PIN changed in the app, or pin field never set.","commonSituations":"User changed the Roborock app lock-screen PIN; passing an empty/default pin when the device has one configured; copying the wrong credential into the client config.","solutions":["Verify the PIN in the Roborock app and update the client's pin field","Re-check which device the pin belongs to (per-device PINs)","Clear the device PIN in the app if you intend to connect without one","Ensure the pin is set on the client before Dial"],"exampleFix":"// before\nc := NewClient(...)\nc.pin = \"0000\" // stale\nc.CheckHomesecPassword()\n// after\nc.pin = \"1234\" // current PIN from the Roborock app\nc.CheckHomesecPassword()","handlingStrategy":"validation","validationCode":"if c.pin == \"\" {\n    return errors.New(\"device PIN required before CheckHomesecPassword\")\n}\n// verify pin format (e.g. 4-8 digits)\nif matched, _ := regexp.MatchString(`^\\d{4,8}$`, c.pin); !matched {\n    return errors.New(\"pin format looks invalid\")\n}","typeGuard":null,"tryCatchPattern":"err := client.CheckHomesecPassword()\nif err != nil && err.Error() == \"wrong pin code\" {\n    return ErrInvalidPin // surface a typed error to prompt the user for the PIN\n}","preventionTips":["Fetch the PIN from secure config, not hardcoded defaults","Update stored PINs whenever the user changes them in the Roborock app","Prompt the user interactively on first connect instead of guessing"],"tags":["authentication","pin","roborock"],"backgroundTag":"authentication-required","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}