Skip to content

LoginResponse.token: pydantic ValidationError при повторном логине по сохранённому токену - Max API не возвращает token в ответе #55

@Arondy

Description

@Arondy

Описание

При повторном запуске клиента, когда work_dir/session.db уже содержит валидный токен (т.е. SMS-авторизация была пройдена ранее), pymax падает с pydantic_core._pydantic_core.ValidationError на этапе Opcode.LOGIN. Сервер Max API в ответе на повторный login не возвращает поле token, а pydantic-модель LoginResponse в pymax объявляет его обязательным.

Сравнение ответов сервера:

  • Через SMS + 2FA: ['chats', 'config', 'contacts', 'messages', 'presence', 'profile', 'time', 'token', 'updates']
  • Через token из session.db: ['chats', 'config', 'contacts', 'messages', 'presence', 'profile', 'time', 'updates']

Похоже, сервер Max выдаёт новый token только при первичной авторизации, а на повторных логинах (включая вариант с chatsSync=-1 для полной синхронизации) отдаёт payload без него - т.к. старый токен всё ещё валиден.

Шаги для воспроизведения

  1. Сбросить кэш.
  2. Пройти авторизацию: ввести SMS-код и 2FA-пароль. Дождаться, пока бот стартует и отправит тестовое сообщение.
  3. Завершить процесс.
  4. Снова запустить скрипт.

Ожидаемый результат

Клиент успешно проходит Opcode.LOGIN по сохранённому токену, поднимает сессию, вызывает on_start и продолжает работу. Токен при необходимости продлевается.

Фактический результат

pydantic_core._pydantic_core.ValidationError: 1 validation error for LoginResponse
token
  Field required [type=missing, input_value={'profile': {'contact': {...}, 'updates': 1}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.12/v/missing

Стек:

File "pymax\app.py", line 134, in start
    response = await self.api.auth.login(self.config.device.user_agent)
File "pymax\api\auth\service.py", line 112, in login
    return await self.mobile_login()
File "pymax\api\auth\service.py", line 131, in mobile_login
    login_response = require_payload_model(response, LoginResponse)
File "pymax\api\response.py", line 94, in require_payload_model
    return model.model_validate(response.payload)

После этого срабатывает await self.close() в base.py:start(), что даёт вторичный ssl.SSLError: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY].

Дополнительно

  • pymax: 2.1.1
  • Python: 3.13
  • Client: Client(phone, work_dir, session_name, extra_config=ExtraConfig(...))
  • user_agent зафиксирован через ExtraConfig(user_agent=MobileUserAgentPayload(...)), но проблема воспроизводится и с рандомным UA из generate_user_agent().
  • SyncOverrides(chats_sync=-1) для принудительной полной синхронизации не помогает - сервер всё равно не возвращает token.
  • device_id и userAgent в handshake совпадают между запусками

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions