{"record":{"id":"cbc9bc0b67257f1b","repo":"commaai/openpilot","slug":"no-redirect-implemented-for-method-method","errorCode":null,"errorMessage":"no redirect implemented for method {method}","messagePattern":"no redirect implemented for method (.+?)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"openpilot/tools/lib/auth.py","lineNumber":94,"sourceCode":"      'prompt': 'select_account',\n    })\n    return 'https://accounts.google.com/o/oauth2/auth?' + urlencode(params)\n  elif method == 'github':\n    params.update({\n      'client_id': '28c4ecb54bb7272cb5a4',\n      'scope': 'read:user',\n    })\n    return 'https://github.com/login/oauth/authorize?' + urlencode(params)\n  elif method == 'apple':\n    params.update({\n      'client_id': 'ai.comma.login',\n      'response_type': 'code',\n      'response_mode': 'form_post',\n      'scope': 'name email',\n    })\n    return 'https://appleid.apple.com/auth/authorize?' + urlencode(params)\n  else:\n    raise NotImplementedError(f\"no redirect implemented for method {method}\")\n\n\ndef login(method):\n  # Let the OS select an available port to avoid colliding with other services.\n  web_server = ClientRedirectServer(('localhost', 0), ClientRedirectHandler)\n  oauth_uri = auth_redirect_link(method, web_server.server_port)\n  print(f'To sign in, use your browser and navigate to {oauth_uri}')\n  webbrowser.open(oauth_uri, new=2)\n\n  while True:\n    web_server.handle_request()\n    if 'code' in web_server.query_params:\n      break\n    elif 'error' in web_server.query_params:\n      print('Authentication Error: \"{}\". Description: \"{}\" '.format(\n        web_server.query_params['error'],\n        web_server.query_params.get('error_description')), file=sys.stderr)\n      break","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/commaai/openpilot/blob/516ec1e68203439a73f340f1d0b3b91eabc626ee/openpilot/tools/lib/auth.py#L76-L112","documentation":"auth_redirect_link() builds an OAuth authorize URL and only supports 'google', 'github', and 'apple' (there is also a provider-id map earlier in the function). Any other method string hits the else branch and raises NotImplementedError. This is an exhaustive-match guard over the supported login providers.","triggerScenarios":"Calling auth_redirect_link(method) or login(method) with e.g. 'microsoft', 'email', or a typo like 'Github' (case-sensitive); code enumerating a config-driven provider list that includes names never implemented.","commonSituations":"User typing the provider name wrong on the CLI; new provider added to config but not to the three branches; case mismatch from user input.","solutions":["Use one of the exact lowercase names: 'google', 'github', or 'apple'","If surfacing this in a CLI, validate/normalize method against {'google','github','apple'} before calling","To add a provider, extend the provider-id map and add a branch returning its authorize URL"],"exampleFix":"# before\nlogin('gmail')\n\n# after\nSUPPORTED = {'google', 'github', 'apple'}\nmethod = method.lower().strip()\nassert method in SUPPORTED, f\"unsupported auth method {method!r}; choose from {sorted(SUPPORTED)}\"\nlogin(method)","handlingStrategy":"validation","validationCode":"SUPPORTED_AUTH = {'google', 'github', 'apple'}\nassert method.lower() in SUPPORTED_AUTH, f\"auth method must be one of {sorted(SUPPORTED_AUTH)}\"","typeGuard":"def is_supported_auth_method(method: str) -> bool:\n    \"\"\"True when method is an implemented OAuth provider name.\"\"\"\n    return isinstance(method, str) and method.lower() in {'google', 'github', 'apple'}","tryCatchPattern":"try:\n    login(method)\nexcept NotImplementedError as e:\n    raise SystemExit(f'{e}; supported: google, github, apple') from e","preventionTips":["Restrict CLI choices to the three providers (argparse choices=['google','github','apple'])","Normalize case/whitespace on user input before it reaches auth_redirect_link"],"tags":["authentication","oauth","not-implemented","openpilot"],"backgroundTag":null,"analyzedSha":"516ec1e68203439a73f340f1d0b3b91eabc626ee","analyzedAt":"2026-08-15T00:17:37.461Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}