{"record":{"id":"0df2b78990df9495","repo":"xtekky/gpt4free","slug":"failed-to-save-auth-result-get-dict-n-type-e","errorCode":null,"errorMessage":"Failed to save: {auth_result.get_dict()}\\n{type(e).__name__}: {e}","messagePattern":"Failed to save: (.+?)\\\\n(.+?): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"g4f/providers/base_provider.py","lineNumber":453,"sourceCode":"        if \"api_key\" not in kwargs:\n            raise MissingAuthError(f\"API key is required for {cls.__name__}\")\n        return AuthResult()\n\n    @classmethod\n    def write_cache_file(cls, cache_file: Path, auth_result: AuthResult = None):\n        if auth_result is not None:\n            cache_file.parent.mkdir(parents=True, exist_ok=True)\n            try:\n\n                def toJSON(obj):\n                    if hasattr(obj, \"get_dict\"):\n                        return obj.get_dict()\n                    return str(obj)\n\n                with cache_file.open(\"w\") as cache_file:\n                    json.dump(auth_result, cache_file, default=toJSON)\n            except TypeError as e:\n                raise RuntimeError(\n                    f\"Failed to save: {auth_result.get_dict()}\\n{type(e).__name__}: {e}\"\n                )\n        # elif cache_file.exists():\n        #    cache_file.unlink()\n\n    @classmethod\n    def get_auth_result(cls) -> AuthResult:\n        \"\"\"\n        Retrieves the authentication result from cache.\n        \"\"\"\n        cache_file = cls.get_cache_file()\n        if cache_file.exists():\n            try:\n                with cache_file.open(\"r\") as f:\n                    return AuthResult(**json.load(f))\n            except json.JSONDecodeError:\n                cache_file.unlink()\n                raise MissingAuthError(f\"Invalid auth file: {cache_file}\")","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/providers/base_provider.py#L435-L471","documentation":"RuntimeError raised inside AsyncAuthedProvider.write_cache_file when json.dump of the AuthResult fails with TypeError while persisting the auth cache to auth_<Provider>.json. It chains the original TypeError and includes auth_result.get_dict() in the message, so the failing object is visible. It indicates the auth result contains an object the toJSON fallback (str()) could not serialize — i.e. get_dict() itself returned or threw on non-serializable content.","triggerScenarios":"A provider's on_auth_async returns an AuthResult holding custom objects whose get_dict() returns nested non-JSON-serializable values (bytes, datetime, requests objects); the write path then hits TypeError from json.dump and re-raises as RuntimeError.","commonSituations":"Custom AsyncAuthedProvider subclasses added by downstream projects; provider upgrades that add new fields (e.g. raw HTTP sessions or cookie jars) to AuthResult; disk state is fine — the failure is purely serialization.","solutions":["Read the embedded get_dict() dump in the message to identify which field is non-serializable.","Fix the provider's AuthResult so get_dict() returns plain JSON types (str/int/float/bool/list/dict) — convert bytes/datetimes in get_dict.","As a caller, delete the cache file and re-authenticate after fixing the serialization, so a partial file is not reused.","If you do not control the subclass, catch RuntimeError around the first authenticated call and report it as a provider bug."],"exampleFix":"// before\nclass MyResult(AuthResult):\n    def get_dict(self) -> dict:\n        return {'token': self.session, 'expiry': self.expires}  # session is a requests.Session\n\n// after\nclass MyResult(AuthResult):\n    def get_dict(self) -> dict:\n        return {'token': self.session.headers['Authorization'], 'expiry': str(self.expires)}","handlingStrategy":"try-catch","validationCode":"import json\nd = auth_result.get_dict()\njson.dumps(d)  # raises TypeError here (before caching) if any field is non-serializable","typeGuard":null,"tryCatchPattern":"try:\n    await provider.create_async_generator(model, messages, api_key=key)\nexcept RuntimeError as e:\n    if 'Failed to save' in str(e):\n        logging.error('auth cache serialization bug in provider %s: %s', provider.__name__, e)\n        # the request itself may have succeeded; treat as non-fatal but report upstream\n    else:\n        raise","preventionTips":["Subclass authors: make get_dict() return only JSON primitives.","Smoke-test get_dict() with json.dumps() in unit tests for custom AuthResults.","Delete the possibly-partial cache file after this error before retrying."],"tags":["serialization","auth-cache","json","g4f"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}