{"record":{"id":"96bb7a9d2391a13f","repo":"AlexxIT/go2rtc","slug":"invalid-auth-type","errorCode":null,"errorMessage":"invalid auth type","messagePattern":"invalid auth type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/ring/api.go","lineNumber":172,"sourceCode":")\n\nfunc NewRestClient(auth interface{}, onTokenRefresh func(string)) (*RingApi, error) {\n\tvar cacheKey string\n\n\t// Create cache key based on auth data\n\tswitch a := auth.(type) {\n\tcase RefreshTokenAuth:\n\t\tif a.RefreshToken == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"refresh token is required\")\n\t\t}\n\t\tcacheKey = \"refresh:\" + a.RefreshToken\n\tcase EmailAuth:\n\t\tif a.Email == \"\" || a.Password == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"email and password are required\")\n\t\t}\n\t\tcacheKey = \"email:\" + a.Email + \":\" + a.Password\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid auth type\")\n\t}\n\n\tcacheMutex.Lock()\n\tdefer cacheMutex.Unlock()\n\n\tif cachedClient, ok := clientCache[cacheKey]; ok {\n\t\t// Check if token is not nil and not expired\n\t\tif cachedClient.authToken != nil && time.Now().Before(cachedClient.tokenExpiry) {\n\t\t\tcachedClient.onTokenRefresh = onTokenRefresh\n\t\t\treturn cachedClient, nil\n\t\t}\n\t}\n\n\tclient := &RingApi{\n\t\thttpClient:     &http.Client{Timeout: defaultTimeout},\n\t\tonTokenRefresh: onTokenRefresh,\n\t\thardwareID:     generateHardwareID(),\n\t\tauth:           auth,","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/ring/api.go#L154-L190","documentation":"The Ring client factory only accepts RefreshTokenAuth or EmailAuth; any other auth type (nil, a wrong struct type, or a different interface value) falls into the default branch and is rejected with this error. It is a strict type check on the auth argument.","triggerScenarios":"Passing nil as auth, a pointer to EmailAuth/RefreshTokenAuth instead of the value type (type switch is on values), or some other credential struct the factory does not know.","commonSituations":"Passing &ring.EmailAuth{...} (pointer) into a value-typed type switch; passing credentials from another library's auth type; calling the factory without any auth argument.","solutions":["Pass ring.RefreshTokenAuth{...} or ring.EmailAuth{...} by value, not a pointer or foreign type.","If you hold a pointer, dereference it before passing.","Check the exact accepted types in pkg/ring/api.go and match them.","Default to RefreshTokenAuth, the recommended auth mode."],"exampleFix":"// before\nclient, err := ring.NewClient(&ring.EmailAuth{Email: e, Password: p}) // pointer rejected\n// after\nclient, err := ring.NewClient(ring.EmailAuth{Email: e, Password: p})","handlingStrategy":"type-guard","validationCode":"switch a := auth.(type) {\ncase ring.RefreshTokenAuth, ring.EmailAuth:\n    // ok\ndefault:\n    return errors.New(\"auth must be ring.RefreshTokenAuth or ring.EmailAuth (by value)\")\n}","typeGuard":"func validRingAuth(a any) bool {\n    switch a.(type) {\n    case ring.RefreshTokenAuth, ring.EmailAuth:\n        return true\n    }\n    return false\n}","tryCatchPattern":"client, err := ring.NewClient(auth)\nif err != nil && err.Error() == \"invalid auth type\" {\n    return fmt.Errorf(\"wrong auth type %T passed to ring.NewClient: %w\", auth, err)\n}","preventionTips":["Pass auth structs by value, never pointers, into the factory","Do not pass foreign/other-library credential types","Centralize auth construction in one helper so the type is checked once","Add a compile-time usage example in tests to catch type drift"],"tags":["go","ring","auth","argument"],"backgroundTag":"invalid-argument-value","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"}