fix: fetch the latest user agreement version instead of hardcoding it - #960
Open
xiaoyaner0201 wants to merge 1 commit into
Open
xiaoyaner0201 wants to merge 1 commit into
xiaoyaner0201 wants to merge 1 commit into
Conversation
`code_login_v4` sent a hardcoded `majorVersion: 14`/`minorVersion: 0` with the
login request. The server rejects a stale agreement version with code 3006,
which surfaces as `RoborockInvalidUserAgreement` ("User agreement must be
accepted again - or you are attempting to use the Mi Home app account").
The current version is not 14 on any server today, and it differs per server
and per country, so it cannot be hardcoded:
| server | latest majorVersion.minorVersion |
| ------ | -------------------------------- |
| cniot | 19.0 |
| usiot | 16.0 (country=US) |
| euiot | 15.1 |
| ruiot | 15.0 |
Because the value is stale server-side rather than account-side, accepting the
agreement again in the app cannot clear it, which is why the usual
revoke-and-re-accept workaround does not help.
Query `/api/v3/app/agreement/latest` (the endpoint already named in the removed
comment) and send the returned version, falling back to the previous constants
so a failed lookup never blocks login. `minorVersion` is taken from the response
too, since euiot currently reports 15.1.
Lash-L
reviewed
Sep 15, 2026
Lash-L
left a comment
Collaborator
There was a problem hiding this comment.
So the reason I didn't do this was I did not know what happened if a new agreement version was added that the user had not agreed with if we would be able to login or if we would get a failure stating that we need to resign the agreement.
But diving into some of the code, I think this will be okay and work.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
code_login_v4sends a hardcoded user agreement version with the login request:The server rejects a stale agreement version with code
3006, which is raised asRoborockInvalidUserAgreement:Note the server's own message: "user agreement version is not up-to-date". The
problem is the version number, not the user's acceptance state.
Why the usual workaround cannot fix it
The documented workaround is to revoke and re-accept the agreement in the app. That
cannot clear this error, because nothing about the account is wrong — the constant sent
by this library is stale. This matches #784, where a user followed that advice
repeatedly across two months and several releases without success.
Measurement
14is not the current version on any server today, and the version differs per serverand per country:
?country=majorVersion.minorVersionReproduce:
Two details worth noting:
usiotwith a non-UScountrystill returns14, which is likely why this wentunnoticed for some users while failing for others.
minorVersioncannot be hardcoded to0either —euiotcurrently reports15.1.Fix
Query
/api/v3/app/agreement/latest(the endpoint already named in the removed comment)and send the version it returns. If the lookup fails, fall back to the previous constants
so that login is never blocked by this extra request.
Tests
Two regression tests added:
test_code_login_v4_uses_latest_agreement_version— asserts the version sent on logincomes from the agreement endpoint. It asserts the observable request payload rather
than the helper, so any correct implementation passes.
test_code_login_v4_agreement_version_fallback— asserts login still succeeds with thefallback constants when the lookup raises.
Verified by reverting only the production change and keeping the tests:
With the fix applied:
Verified against a live account
Confirmed end-to-end on a
cniotaccount that could not log in before this change:login now succeeds and the device list loads. Before the fix the same account failed
with
3006on every attempt.Closes #784