Tell iCloud being refused apart from terms of service - #223
Merged
Merged
Conversation
Issue #221. Apple took the password and the code, then the com.apple.mobileme delegate refused the account: status=1, status-message "A server problem is blocking Apple ID sign in. Try signing in later." There was no localizedError in the response at all. That matters because the response has two independent error channels and terms arrive on only one of them. classifyLoginFailure mapped every MobileMeDelegateError to REASON_TERMS, so the reporter - whose terms were fine, as iCloud on the web confirmed - was taken to a terms screen, shown an empty document list, and told that accepting terms was the remedy. Splits REASON_ICLOUD_REFUSED out of it, branching on whether the response used the localizedError channel at all. The new sentence says authentication worked, says it is not about terms, and passes on what the neighbouring clients have worked out: this turns up on Apple IDs that have never been used with an Apple device, and completing the account at appleid.apple.com is what clears it. macless-haystack#84, #86 and #87 are where that comes from, and they are credited in the comments rather than only here. Deliberately not REASON_APPLE_DECLINED. That one advises waiting and offers the Anisette server route; Apple's own wording here also says to try later, and across those clients it does not clear on its own. Sending somebody to retry an unchanged sign-in forever is worse than naming the account. Reads error.localized_error rather than the names_a_localized_error property added in parawanderer/FindMy.py#5, so this works against the pinned commit and does not drag rule 14's four files into the fix. Six bridge tests and one Espresso test. Two of the bridge tests go red against the old classification, verified by reverting the branch. The Java is not compiled here - this machine has no Android toolchain - so the instrumented test and the build are CI's word, not mine. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The same split as the app side, in the other two programs that make this call. Both the wizard and the CLI answered every MobileMeDelegateError with the terms flow, because terms were the only cause with a remedy here. Neither of them lied about it - the wizard fetches, finds nothing and says "this is something else", and the CLI asks before fetching and says the same. That honesty is why this never arrived as an exporter bug report. It is still a round trip to Apple to discover something the response already said, and it still leaves somebody at a dead end holding Apple's word "server problem", which reads as "wait" when waiting is exactly what does not work. not_a_terms_problem() in icloud.py is the shared decision, next to ExportSourceError and the sign-in that raises it, so the wizard and the CLI cannot drift apart on it the way three screens in the app once did. The message says sign-in worked, says it is not terms, quotes Apple verbatim because that string is the only evidence a report can carry, and passes on the remedy from dchristl/macless-haystack#84, #86 and #87 - appleid.apple.com and a payment method - as somebody else's finding rather than as fact. It contradicts Apple's own "try signing in later" on purpose. Nine tests, both branches of the decision. 657 passed on the exporter suite, flake8 clean, and pyright unchanged at its pre-existing count. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 task
Picks up parawanderer/FindMy.py#5, which stops the library's own delegate error advising the terms flow when the response never used that channel. All four sites together, per rule 14: the Chaquopy install line, the bridge tests' requirements, the exporter's pyproject, and uv.lock via `uv lock`. test_the_whole_repository_pins_one_findmy and test_pinned_versions_match_the_app_build both pass. Nothing user-facing depends on this any more - the app and the exporter each produce their own sentence for this case now, so the library's message is read by developers rather than shown to anyone. It is still the text that lands in a log or a stack trace, which is where the next person diagnosing this will meet it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This branch was successfully deployed
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.
Closes #221.
Apple took the password and the code, then the
com.apple.mobilemedelegate refused the account:status=1,status-message='A server problem is blocking Apple ID sign in. Try signing in later.', and nolocalizedErrorin the response at all.That is the whole finding. The response has two independent error channels and terms arrive on only one of them.
classifyLoginFailuremapped everyMobileMeDelegateErrortoREASON_TERMS, so the reporter — whose terms were fine, as iCloud on the web confirmed — was taken to a terms screen, shown an empty document list, and told that accepting terms was the remedy.The change
REASON_ICLOUD_REFUSEDsplits out ofREASON_TERMS, branching on whether the response used thelocalizedErrorchannel at all. The new sentence says authentication worked, says it is not about terms, and passes on what the neighbouring clients have worked out: this turns up on Apple IDs that have never been used with an Apple device, and completing the account at appleid.apple.com is what clears it.That knowledge is macless-haystack#84, #86 and #87, where the same delegate status arrives both with this wording and with "Account limit reached". They are credited in the source comments, not only here.
Deliberately not
REASON_APPLE_DECLINED: that advises waiting and offers the Anisette server route. Apple's own wording here also says to try later, and across those clients it does not clear on its own, so that advice is a loop. A different machine identity changes nothing about an account Apple will not open, which is why the test also pins that the server button stays hidden.Reads
error.localized_errorrather than thenames_a_localized_errorproperty added in parawanderer/FindMy.py#5, so this works against the pinned commit and does not drag rule 14's four files into the fix. That PR fixes the same confusion in the library's own message and is independent of this one.Tests
Six bridge tests and one Espresso test. Two of the bridge tests go red against the old classification — verified by reverting the branch and watching them fail, with the old run printing the misleading terms advice.
The string is in all ten locales via
add_strings.py;--checkpasses at 376 strings.Not verified here: this machine has no Android toolchain, so nothing Java was compiled and the instrumented test has not run. The build and the emulator suite are CI's word, not mine.
🤖 Generated with Claude Code