You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
zones/changes may use metaSyncToken, not syncToken — pagination possibly broken #430
Apple's archived reference documents zones/changes as taking and returning a metaSyncToken, but MistKit sends and reads syncToken. If the documentation is right, fetchZoneChanges / fetchAllZoneChanges pagination is silently broken — the server would ignore the unrecognized key and return the first page forever, which a stuck-token guard would mask as "no more changes" rather than surface as an error.
Surfaced during #386 verification and reiterated in #429. Deliberately not changed in either PR, because the evidence is genuinely contradictory and this needs a live response to settle, not a doc-driven guess.
Against — the same Apple page contradicts itself: its moreComing description refers back to "the included syncToken key".
In this repo, openapi.yaml shows the same split personality — the description says "meta-sync token" while the property is named syncToken:
# openapi.yaml — zones/changessummary: Fetch Zone Changesdescription: Get all changed zones relative to a meta-sync token...properties:
syncToken:
type: stringdescription: Meta-sync token from previous operation
metaSyncToken appears nowhere in the repository (grep -rn metaSyncToken . → no matches), so if Apple's field name is correct, this has never worked.
Why it may not have been noticed
zones/changes is deprecated by Apple in favor of changes/database (see #401), so it is plausibly under-exercised. As of #429, fetchZoneChanges / fetchAllZoneChanges are marked @available(*, deprecated) and fetchDatabaseChanges / fetchAllDatabaseChanges are the supported path — which lowers the severity here but does not resolve the question.
How to settle it
This needs a live call against a real container, not more doc reading:
Call zones/changes with no token, note the returned token key name in the raw response body.
Make a zone-level change, then re-request passing the token back as syncToken.
If the same zone set is returned unchanged, the key is wrong; retry as metaSyncToken and compare.
MistDemo can drive this — the middleware logs full request/response bodies at .debug (com.brightdigit.MistKit.middleware), so the raw key names are directly observable.
Outcome
If metaSyncToken is correct → fix openapi.yaml, regenerate, and add a note that the deprecated endpoint's pagination was previously broken.
If syncToken is correct → fix the misleading "meta-sync token" wording in openapi.yaml so this doesn't get re-raised.
Either way the spec should stop describing a field by a name it doesn't use.
Top-level keys are exactly [moreComing, metaSyncToken, zones]. syncToken is absent.
2. Round-trip proves the pagination is broken. Same baseline token sent back under each key:
Request body
Zones returned
Result
baseline (no token)
40, token AQAAAaBJitS1
—
{"syncToken": …} — what MistKit sends today
40 again
key ignored, page 1 replayed
{"metaSyncToken": …}
0
token honored, advanced correctly
So fetchZoneChanges/fetchAllZoneChanges have never paginated. The server accepts the request (HTTP 200) and silently discards the unrecognized key.
Note the failure mode differs from this issue's prediction: the stuck-token guard at CloudKitService+FetchAllZoneChanges.swift:108-115 requires zones.isEmpty, so on a non-empty database this presents as duplicate zones accumulating until maxPages trips zonePaginationLimitExceeded — not a silent 'no more changes'.
Fix: rename the wire key to metaSyncToken in openapi.yaml (request and response) and regenerate. Keep the Swift-level names (ZoneChangesResult.syncToken, the syncToken: argument labels) unchanged — MistKit imports the generated module as internal import, so a wire-key rename is not source-breaking for MistKit consumers. Also update the hardcoded "syncToken" JSON literals in Tests/MistKitTests/CloudKitService/FetchZoneChanges/…+Helpers.swift.
Activity
leogdion commentedon Aug 28, 2026
Confirmed by live container test —
metaSyncTokenis correctRan against
iCloud.com.brightdigit.MistDemo/development/ private DB,POST zones/changes, web-auth credentials.1. The response uses
metaSyncToken, notsyncToken:{ "moreComing": false, "metaSyncToken": "AQAAAaBJidqD", "zones": [ { "zoneID": { "zoneName": "…", "ownerRecordName": "…", "zoneType": "REGULAR_CUSTOM_ZONE" }, "deleted": true }, … ] }Top-level keys are exactly
[moreComing, metaSyncToken, zones].syncTokenis absent.2. Round-trip proves the pagination is broken. Same baseline token sent back under each key:
AQAAAaBJitS1{"syncToken": …}— what MistKit sends today{"metaSyncToken": …}So
fetchZoneChanges/fetchAllZoneChangeshave never paginated. The server accepts the request (HTTP 200) and silently discards the unrecognized key.Note the failure mode differs from this issue's prediction: the stuck-token guard at
CloudKitService+FetchAllZoneChanges.swift:108-115requireszones.isEmpty, so on a non-empty database this presents as duplicate zones accumulating untilmaxPagestripszonePaginationLimitExceeded— not a silent 'no more changes'.Fix: rename the wire key to
metaSyncTokeninopenapi.yaml(request and response) and regenerate. Keep the Swift-level names (ZoneChangesResult.syncToken, thesyncToken:argument labels) unchanged — MistKit imports the generated module asinternal import, so a wire-key rename is not source-breaking for MistKit consumers. Also update the hardcoded"syncToken"JSON literals inTests/MistKitTests/CloudKitService/FetchZoneChanges/…+Helpers.swift.Reopening scope: this stays in v1.0.0-beta.4.
Rename the zones/changes wire token to metaSyncToken (#430)
Model per-zone failures on zones/modify; clarify zones/changes syncToken
Rename the zones/changes wire token to metaSyncToken (#430)
Model per-zone failures on zones/modify; clarify zones/changes syncToken
Rename the zones/changes wire token to metaSyncToken (#430)
Model per-zone failures on zones/modify; clarify zones/changes syncToken
Rename the zones/changes wire token to metaSyncToken (#430)
modifyZones per-zone failures (#431) + zones/changes metaSyncToken (#430
modifyZones per-zone failures (#431) + zones/changes metaSyncToken (#430
v1.0.0 beta.4 (#439)
leogdion commentedon Aug 29, 2026
Fixed in #443 — zones/changes wire key renamed to
metaSyncToken(verified against live container).