Repository: matrix-org/matrix-rust-sdk (2025-08-12T15:53:21Z)

Issue:
`sync_once` does not use `client.sync_token`
As `Client::sync_token` is private, and `Client::sync_once` [does not fall back to it](https://github.com/matrix-org/matrix-rust-sdk/blob/cbfa1340875d9d5ceec718fc1fd6a8e23ad47810/crates/matrix-sdk/src/client/mod.rs#L2167) when no sync token is provided, it's not possible to use `sync_once` with a client's remembered sync token.

I assume since `Client::sync_with_result_callback` [does fall back to the client's `sync_token`](https://github.com/matrix-org/matrix-rust-sdk/blob/cbfa1340875d9d5ceec718fc1fd6a8e23ad47810/crates/matrix-sdk/src/client/mod.rs#L2403-L2405), that this behaviour is likely also intended for `sync_once`.

It's an easy fix, but I thought I should open an issue as I'm not sure what the intended behaviour is (i.e. should `sync_token` be made public again? or should `sync_once` fall back to `sync_token` when a token isn't provided)


Discussion:
Just in case anyone else wants something that acts like a `sync_once` but also uses the saved sync token, you can use this
```rust
client.sync_with_callback(sync_settings, |_| async move { LoopCtrl::Break }).await?;
``` 
I ran into this again, so I think we should do something better. The simplest thing to do would be to set the `SyncSettings::token` to something, if we have something in the store, even in `sync_once()` and all, for sync v2. Alternatively: we could also make it so that `SyncSettings::token` is an enum of three variants:

- use a specific token (i.e. the current `Some()`)
- force using no token (i.e. force the current `None`)
- reuse the previous token if we had one (default)



Patch:
diff --git a/crates/matrix-sdk/CHANGELOG.md b/crates/matrix-sdk/CHANGELOG.md
index 84f41e13065..8c134320fe0 100644
--- a/crates/matrix-sdk/CHANGELOG.md
+++ b/crates/matrix-sdk/CHANGELOG.md
@@ -38,6 +38,8 @@ All notable changes to this project will be documented in this file.
 
 ### Refactor
 
+- [**breaking**] `SyncSettings` token is now `SyncToken` enum type which has default behaviour of `SyncToken::ReusePrevious` token. This breaks `Client::sync_once`.
+  For old behaviour, set the token to `SyncToken::NoToken` with the usual `SyncSettings::token` setter.
 - [**breaking**] Change the upload_encrypted_file and make it clone the client instead of owning it. The lifetime of the `UploadEncryptedFile` request returned by `Client::upload_encrypted_file()` only depends on the request lifetime now.
 - [**breaking**] Add an `IsPrefix = False` bound to the `account_data()` and
   `fetch_account_data_static()` methods of `Account`. These methods only worked
diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs
index 73d41274dd4..17475973203 100644
--- a/crates/matrix-sdk/src/client/mod.rs
+++ b/crates/matrix-sdk/src/client/mod.rs
@@ -82,7 +82,7 @@ use crate::{
         matrix::MatrixAuth, oauth::OAuth, AuthCtx, AuthData, ReloadSessionCallback,
         SaveSessionCallback,
     },
-    config::RequestConfig,
+    config::{RequestConfig, SyncToken},
     deduplicating_handler::DeduplicatingHandler,
     error::HttpResult,
     event_cache::EventCache,
@@ -2304,9 +2304,15 @@ impl Client {
             error!(error = ?e, "Error while sending outgoing E2EE requests");
         }
 
+        let token = match sync_settings.token {
+            SyncToken::Specific(token) => Some(token),
+            SyncToken::NoToken => None,
+            SyncToken::ReusePrevious => self.sync_token().await,
+        };
+
         let request = assign!(sync_events::v3::Request::new(), {
             filter: sync_settings.filter.map(|f| *f),
-            since: sync_settings.token,
+            since: token,
             full_state: sync_settings.full_state,
             set_presence: sync_settings.set_presence,
             timeout: sync_settings.timeout,
@@ -2604,10 +2610,6 @@ impl Client {
         let mut timeout = None;
         let mut last_sync_time: Option<Instant> = None;
 
-        if sync_settings.token.is_none() {
-            sync_settings.token = self.sync_token().await;
-        }
-
         let parent_span = Span::current();
 
         async_stream::stream!({
diff --git a/crates/matrix-sdk/src/config/mod.rs b/crates/matrix-sdk/src/config/mod.rs
index 4716b25f735..67cc4d58ab1 100644
--- a/crates/matrix-sdk/src/config/mod.rs
+++ b/crates/matrix-sdk/src/config/mod.rs
@@ -19,4 +19,4 @@ mod sync;
 
 pub use matrix_sdk_base::store::StoreConfig;
 pub use request::RequestConfig;
-pub use sync::SyncSettings;
+pub use sync::{SyncSettings, SyncToken};
diff --git a/crates/matrix-sdk/src/config/sync.rs b/crates/matrix-sdk/src/config/sync.rs
index 04dd27c0240..7468a98c8a0 100644
--- a/crates/matrix-sdk/src/config/sync.rs
+++ b/crates/matrix-sdk/src/config/sync.rs
@@ -19,6 +19,40 @@ use ruma::{api::client::sync::sync_events, presence::PresenceState};
 
 const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30);
 
+/// Token to be used in the next sync request.
+#[derive(Clone, Default, Debug)]
+pub enum SyncToken {
+    /// Provide a specific token.
+    Specific(String),
+    /// Enforce no tokens at all.
+    NoToken,
+    /// Use a previous token if the client saw one in the past, and none
+    /// otherwise.
+    ///
+    /// This is the default value.
+    #[default]
+    ReusePrevious,
+}
+
+impl<T> From<T> for SyncToken
+where
+    T: Into<String>,
+{
+    fn from(token: T) -> SyncToken {
+        SyncToken::Specific(token.into())
+    }
+}
+
+impl SyncToken {
+    /// Convert a token that may exist into a [`SyncToken`]
+    pub fn from_optional_token(maybe_token: Option<String>) -> SyncToken {
+        match maybe_token {
+            Some(token) => SyncToken::Specific(token),
+            None => SyncToken::default(),
+        }
+    }
+}
+
 /// Settings for a sync call.
 #[derive(Clone)]
 pub struct SyncSettings {
@@ -26,7 +60,7 @@ pub struct SyncSettings {
     pub(crate) filter: Option<Box<sync_events::v3::Filter>>,
     pub(crate) timeout: Option<Duration>,
     pub(crate) ignore_timeout_on_first_sync: bool,
-    pub(crate) token: Option<String>,
+    pub(crate) token: SyncToken,
     pub(crate) full_state: bool,
     pub(crate) set_presence: PresenceState,
 }
@@ -66,7 +100,7 @@ impl SyncSettings {
             filter: None,
             timeout: Some(DEFAULT_SYNC_TIMEOUT),
             ignore_timeout_on_first_sync: false,
-            token: None,
+            token: SyncToken::default(),
             full_state: false,
             set_presence: PresenceState::Online,
         }
@@ -78,8 +112,8 @@ impl SyncSettings {
     ///
     /// * `token` - The sync token that should be used for the sync call.
     #[must_use]
-    pub fn token(mut self, token: impl Into<String>) -> Self {
-        self.token = Some(token.into());
+    pub fn token(mut self, token: impl Into<SyncToken>) -> Self {
+        self.token = token.into();
         self
     }
 
diff --git a/crates/matrix-sdk/src/sync.rs b/crates/matrix-sdk/src/sync.rs
index 77b801c997e..0b42e0d3f6a 100644
--- a/crates/matrix-sdk/src/sync.rs
+++ b/crates/matrix-sdk/src/sync.rs
@@ -315,7 +315,7 @@ impl Client {
 
         match response {
             Ok(r) => {
-                sync_settings.token = Some(r.next_batch.clone());
+                sync_settings.token = r.next_batch.clone().into();
                 Ok(r)
             }
             Err(e) => {


Test patch:
diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/focus_event.rs b/crates/matrix-sdk-ui/tests/integration/timeline/focus_event.rs
index c4350f7a891..61da45b69e4 100644
--- a/crates/matrix-sdk-ui/tests/integration/timeline/focus_event.rs
+++ b/crates/matrix-sdk-ui/tests/integration/timeline/focus_event.rs
@@ -19,7 +19,10 @@ use std::time::Duration;
 use assert_matches2::assert_let;
 use eyeball_im::VectorDiff;
 use futures_util::StreamExt;
-use matrix_sdk::{config::SyncSettings, test_utils::logged_in_client_with_server};
+use matrix_sdk::{
+    config::{SyncSettings, SyncToken},
+    test_utils::logged_in_client_with_server,
+};
 use matrix_sdk_test::{
     ALICE, BOB, JoinedRoomBuilder, SyncResponseBuilder, async_test, event_factory::EventFactory,
     mocks::mock_encryption_state,
@@ -189,7 +192,8 @@ async fn test_new_focused() {
 async fn test_live_aggregations_are_reflected_on_focused_timelines() {
     let room_id = room_id!("!a98sd12bjh:example.org");
     let (client, server) = logged_in_client_with_server().await;
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     let mut sync_response_builder = SyncResponseBuilder::new();
     sync_response_builder.add_joined_room(JoinedRoomBuilder::new(room_id));
diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/pagination.rs b/crates/matrix-sdk-ui/tests/integration/timeline/pagination.rs
index 21235cb6c67..4697e504724 100644
--- a/crates/matrix-sdk-ui/tests/integration/timeline/pagination.rs
+++ b/crates/matrix-sdk-ui/tests/integration/timeline/pagination.rs
@@ -23,7 +23,7 @@ use futures_util::{
 };
 use matrix_sdk::{
     assert_let_timeout,
-    config::SyncSettings,
+    config::{SyncSettings, SyncToken},
     event_cache::RoomPaginationStatus,
     test_utils::{
         logged_in_client_with_server,
@@ -412,7 +412,8 @@ async fn test_wait_for_token() {
     let room_id = room_id!("!a98sd12bjh:example.org");
     let (client, server) = logged_in_client_with_server().await;
 
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     let f = EventFactory::new();
     let mut sync_builder = SyncResponseBuilder::new();
@@ -535,7 +536,8 @@ async fn test_dedup_pagination() {
 async fn test_timeline_reset_while_paginating() {
     let room_id = room_id!("!a98sd12bjh:example.org");
     let (client, server) = logged_in_client_with_server().await;
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     let f = EventFactory::new();
     let mut sync_builder = SyncResponseBuilder::new();
diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/profiles.rs b/crates/matrix-sdk-ui/tests/integration/timeline/profiles.rs
index 60f24dbccb4..5a1b7ef56a4 100644
--- a/crates/matrix-sdk-ui/tests/integration/timeline/profiles.rs
+++ b/crates/matrix-sdk-ui/tests/integration/timeline/profiles.rs
@@ -15,7 +15,10 @@
 use std::{sync::Arc, time::Duration};
 
 use assert_matches::assert_matches;
-use matrix_sdk::{config::SyncSettings, test_utils::logged_in_client_with_server};
+use matrix_sdk::{
+    config::{SyncSettings, SyncToken},
+    test_utils::logged_in_client_with_server,
+};
 use matrix_sdk_common::executor::spawn;
 use matrix_sdk_test::{
     ALICE, BOB, CAROL, DEFAULT_TEST_ROOM_ID, JoinedRoomBuilder, SyncResponseBuilder, async_test,
@@ -34,7 +37,8 @@ use crate::mock_sync;
 #[async_test]
 async fn test_update_sender_profiles() {
     let (client, server) = logged_in_client_with_server().await;
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     let f = EventFactory::new();
     let mut sync_builder = SyncResponseBuilder::new();
diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/queue.rs b/crates/matrix-sdk-ui/tests/integration/timeline/queue.rs
index dba48e7e987..4ce49c6bde2 100644
--- a/crates/matrix-sdk-ui/tests/integration/timeline/queue.rs
+++ b/crates/matrix-sdk-ui/tests/integration/timeline/queue.rs
@@ -18,7 +18,11 @@ use assert_matches::assert_matches;
 use assert_matches2::assert_let;
 use eyeball_im::VectorDiff;
 use futures_util::StreamExt;
-use matrix_sdk::{Error, config::SyncSettings, test_utils::logged_in_client_with_server};
+use matrix_sdk::{
+    Error,
+    config::{SyncSettings, SyncToken},
+    test_utils::logged_in_client_with_server,
+};
 use matrix_sdk_base::store::QueueWedgeError;
 use matrix_sdk_test::{
     ALICE, JoinedRoomBuilder, SyncResponseBuilder, async_test, event_factory::EventFactory,
@@ -314,7 +318,8 @@ async fn test_reloaded_failed_local_echoes_are_marked_as_failed() {
 async fn test_clear_with_echoes() {
     let room_id = room_id!("!a98sd12bjh:example.org");
     let (client, server) = logged_in_client_with_server().await;
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     let f = EventFactory::new();
     let mut sync_builder = SyncResponseBuilder::new();
@@ -397,7 +402,8 @@ async fn test_clear_with_echoes() {
 async fn test_no_duplicate_date_divider() {
     let room_id = room_id!("!a98sd12bjh:example.org");
     let (client, server) = logged_in_client_with_server().await;
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     let mut sync_response_builder = SyncResponseBuilder::new();
     sync_response_builder.add_joined_room(JoinedRoomBuilder::new(room_id));
diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/subscribe.rs b/crates/matrix-sdk-ui/tests/integration/timeline/subscribe.rs
index 9db7bb04442..b606ca1fab2 100644
--- a/crates/matrix-sdk-ui/tests/integration/timeline/subscribe.rs
+++ b/crates/matrix-sdk-ui/tests/integration/timeline/subscribe.rs
@@ -18,7 +18,10 @@ use assert_matches::assert_matches;
 use assert_matches2::assert_let;
 use eyeball_im::VectorDiff;
 use futures_util::StreamExt;
-use matrix_sdk::{config::SyncSettings, test_utils::logged_in_client_with_server};
+use matrix_sdk::{
+    config::{SyncSettings, SyncToken},
+    test_utils::logged_in_client_with_server,
+};
 use matrix_sdk_common::executor::spawn;
 use matrix_sdk_test::{
     ALICE, BOB, GlobalAccountDataTestEvent, JoinedRoomBuilder, SyncResponseBuilder, async_test,
@@ -42,7 +45,8 @@ use crate::mock_sync;
 async fn test_batched() {
     let room_id = room_id!("!a98sd12bjh:example.org");
     let (client, server) = logged_in_client_with_server().await;
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     let f = EventFactory::new();
     let mut sync_builder = SyncResponseBuilder::new();
@@ -84,7 +88,8 @@ async fn test_batched() {
 async fn test_event_filter() {
     let room_id = room_id!("!a98sd12bjh:example.org");
     let (client, server) = logged_in_client_with_server().await;
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
     let f = EventFactory::new();
 
     let mut sync_builder = SyncResponseBuilder::new();
@@ -174,7 +179,8 @@ async fn test_event_filter() {
 async fn test_timeline_is_reset_when_a_user_is_ignored_or_unignored() {
     let room_id = room_id!("!a98sd12bjh:example.org");
     let (client, server) = logged_in_client_with_server().await;
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     let mut sync_builder = SyncResponseBuilder::new();
     sync_builder.add_joined_room(JoinedRoomBuilder::new(room_id));
@@ -289,7 +295,8 @@ async fn test_timeline_is_reset_when_a_user_is_ignored_or_unignored() {
 async fn test_profile_updates() {
     let room_id = room_id!("!a98sd12bjh:example.org");
     let (client, server) = logged_in_client_with_server().await;
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
     let f = EventFactory::new();
 
     let mut sync_builder = SyncResponseBuilder::new();
diff --git a/crates/matrix-sdk/tests/integration/client.rs b/crates/matrix-sdk/tests/integration/client.rs
index 8005dcb6f25..5cb2036bd3c 100644
--- a/crates/matrix-sdk/tests/integration/client.rs
+++ b/crates/matrix-sdk/tests/integration/client.rs
@@ -5,7 +5,7 @@ use eyeball_im::VectorDiff;
 use futures_util::FutureExt;
 use matrix_sdk::{
     authentication::oauth::{error::OAuthTokenRevocationError, OAuthError},
-    config::{RequestConfig, StoreConfig, SyncSettings},
+    config::{RequestConfig, StoreConfig, SyncSettings, SyncToken},
     store::RoomLoadSettings,
     sync::{RoomUpdate, State},
     test_utils::{
@@ -942,7 +942,8 @@ async fn test_test_ambiguity_changes() {
 
     // Initial sync, adds 2 members.
     mock_sync(&server, &*test_json::SYNC, None).await;
-    let response = client.sync_once(SyncSettings::default()).await.unwrap();
+    let response =
+        client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     let room = client.get_room(&DEFAULT_TEST_ROOM_ID).unwrap();
@@ -1015,7 +1016,8 @@ async fn test_test_ambiguity_changes() {
     sync_builder.add_joined_room(joined_room);
 
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
-    let response = client.sync_once(SyncSettings::default()).await.unwrap();
+    let response =
+        client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     let changes = &response.rooms.joined.get(*DEFAULT_TEST_ROOM_ID).unwrap().ambiguity_changes;
@@ -1074,7 +1076,8 @@ async fn test_test_ambiguity_changes() {
     sync_builder.add_joined_room(joined_room);
 
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
-    let response = client.sync_once(SyncSettings::default()).await.unwrap();
+    let response =
+        client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     let changes = &response.rooms.joined.get(*DEFAULT_TEST_ROOM_ID).unwrap().ambiguity_changes;
@@ -1120,7 +1123,8 @@ async fn test_test_ambiguity_changes() {
     sync_builder.add_joined_room(joined_room);
 
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
-    let response = client.sync_once(SyncSettings::default()).await.unwrap();
+    let response =
+        client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     let changes = &response.rooms.joined.get(*DEFAULT_TEST_ROOM_ID).unwrap().ambiguity_changes;
@@ -1166,7 +1170,8 @@ async fn test_test_ambiguity_changes() {
     sync_builder.add_joined_room(joined_room);
 
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
-    let response = client.sync_once(SyncSettings::default()).await.unwrap();
+    let response =
+        client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     let changes = &response.rooms.joined.get(*DEFAULT_TEST_ROOM_ID).unwrap().ambiguity_changes;
@@ -1212,7 +1217,8 @@ async fn test_test_ambiguity_changes() {
     sync_builder.add_joined_room(joined_room);
 
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
-    let response = client.sync_once(SyncSettings::default()).await.unwrap();
+    let response =
+        client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     // Avatar change does not trigger ambiguity change.
@@ -1315,7 +1321,7 @@ async fn test_dms_are_processed_in_any_sync_response() {
     let json_response = sync_response_builder.build_json_sync_response();
 
     mock_sync(&server, json_response, None).await;
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     let room_1 = client.get_room(room_id_1).unwrap();
@@ -1327,7 +1333,7 @@ async fn test_dms_are_processed_in_any_sync_response() {
     let json_response = sync_response_builder.build_json_sync_response();
 
     mock_sync(&server, json_response, None).await;
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     let room_2 = client.get_room(room_id_2).unwrap();
diff --git a/crates/matrix-sdk/tests/integration/notification.rs b/crates/matrix-sdk/tests/integration/notification.rs
index a559f757e85..be74f509ebf 100644
--- a/crates/matrix-sdk/tests/integration/notification.rs
+++ b/crates/matrix-sdk/tests/integration/notification.rs
@@ -1,5 +1,8 @@
 use assert_matches2::assert_matches;
-use matrix_sdk::{config::SyncSettings, sync::Notification};
+use matrix_sdk::{
+    config::{SyncSettings, SyncToken},
+    sync::Notification,
+};
 use matrix_sdk_base::deserialized_responses::RawAnySyncOrStrippedTimelineEvent;
 use matrix_sdk_test::{
     async_test, event_factory::EventFactory, stripped_state_event, sync_state_event, test_json,
@@ -50,7 +53,7 @@ async fn test_notifications_joined() {
     sync_builder.add_joined_room(joined_room);
 
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     assert_pending!(receiver_stream);
@@ -72,7 +75,7 @@ async fn test_notifications_joined() {
     sync_builder.add_joined_room(joined_room);
 
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
 
     let (notif_room_id, notification) = assert_ready!(receiver_stream);
     assert_eq!(notif_room_id, room_id);
diff --git a/crates/matrix-sdk/tests/integration/room/beacon/mod.rs b/crates/matrix-sdk/tests/integration/room/beacon/mod.rs
index 9768ca27e18..a6526db7eab 100644
--- a/crates/matrix-sdk/tests/integration/room/beacon/mod.rs
+++ b/crates/matrix-sdk/tests/integration/room/beacon/mod.rs
@@ -3,7 +3,8 @@ use std::time::{Duration, UNIX_EPOCH};
 use futures_util::{pin_mut, FutureExt, StreamExt as _};
 use js_int::uint;
 use matrix_sdk::{
-    config::SyncSettings, live_location_share::LiveLocationShare,
+    config::{SyncSettings, SyncToken},
+    live_location_share::LiveLocationShare,
     test_utils::mocks::MatrixMockServer,
 };
 use matrix_sdk_test::{
@@ -220,7 +221,8 @@ async fn test_most_recent_event_in_stream() {
         None,
     )
     .await;
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
     let _response = client.sync_once(sync_settings.clone()).await.unwrap();
     server.reset().await;
 
@@ -330,7 +332,8 @@ async fn test_observe_single_live_location_share() {
     )
     .await;
 
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
     let _response = client.sync_once(sync_settings.clone()).await.unwrap();
     server.reset().await;
 
diff --git a/crates/matrix-sdk/tests/integration/room/beacon_info/mod.rs b/crates/matrix-sdk/tests/integration/room/beacon_info/mod.rs
index 65c4c3d3457..3ffcd7964ca 100644
--- a/crates/matrix-sdk/tests/integration/room/beacon_info/mod.rs
+++ b/crates/matrix-sdk/tests/integration/room/beacon_info/mod.rs
@@ -1,7 +1,7 @@
 use std::time::Duration;
 
 use js_int::uint;
-use matrix_sdk::config::SyncSettings;
+use matrix_sdk::config::{SyncSettings, SyncToken};
 use matrix_sdk_test::{async_test, test_json, DEFAULT_TEST_ROOM_ID};
 use ruma::{
     event_id,
@@ -35,7 +35,8 @@ async fn test_start_live_location_share_for_room() {
         .mount(&server)
         .await;
 
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     mock_sync(&server, &*test_json::SYNC, None).await;
 
@@ -134,7 +135,8 @@ async fn test_stop_sharing_live_location() {
         .mount(&server)
         .await;
 
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     mock_sync(
         &server,
diff --git a/crates/matrix-sdk/tests/integration/room/common.rs b/crates/matrix-sdk/tests/integration/room/common.rs
index 6a01b9a478a..19de66484e2 100644
--- a/crates/matrix-sdk/tests/integration/room/common.rs
+++ b/crates/matrix-sdk/tests/integration/room/common.rs
@@ -3,8 +3,10 @@ use std::{collections::BTreeMap, iter, time::Duration};
 use assert_matches2::{assert_let, assert_matches};
 use js_int::uint;
 use matrix_sdk::{
-    config::SyncSettings, room::RoomMember, test_utils::mocks::MatrixMockServer, RoomDisplayName,
-    RoomMemberships,
+    config::{SyncSettings, SyncToken},
+    room::RoomMember,
+    test_utils::mocks::MatrixMockServer,
+    RoomDisplayName, RoomMemberships,
 };
 use matrix_sdk_test::{
     async_test, bulk_room_members, event_factory::EventFactory, sync_state_event, test_json,
@@ -76,7 +78,7 @@ async fn test_room_names() {
     // Room with a canonical alias.
     mock_sync(&server, &*test_json::SYNC, None).await;
 
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     assert_eq!(client.rooms().len(), 1);
@@ -87,7 +89,7 @@ async fn test_room_names() {
     // Room with a name.
     mock_sync(&server, &*test_json::INVITE_SYNC, None).await;
 
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     assert_eq!(client.rooms().len(), 2);
@@ -124,7 +126,7 @@ async fn test_room_names() {
     );
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
 
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     let room = client.get_room(room_id).unwrap();
@@ -174,7 +176,7 @@ async fn test_room_names() {
     ]));
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
 
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     let room = client.get_room(room_id).unwrap();
@@ -194,7 +196,7 @@ async fn test_room_names() {
     );
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
 
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     let room = client.get_room(room_id).unwrap();
@@ -737,7 +739,8 @@ async fn test_event_with_context() {
 async fn test_is_direct() {
     let (client, server) = logged_in_client_with_server().await;
     let own_user_id = client.user_id().unwrap();
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
 
     let bob_member_event = json!({
         "content": {
@@ -853,7 +856,7 @@ async fn test_room_avatar() {
     // Room without avatar.
     mock_sync(&server, &*test_json::SYNC, None).await;
 
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     assert_eq!(client.rooms().len(), 1);
@@ -874,7 +877,7 @@ async fn test_room_avatar() {
     sync_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_event(event));
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
 
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     assert_eq!(room.avatar_url().as_deref(), Some(avatar_url_1));
@@ -893,7 +896,7 @@ async fn test_room_avatar() {
     sync_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_event(event));
     mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
 
-    client.sync_once(SyncSettings::default()).await.unwrap();
+    client.sync_once(SyncSettings::default().token(SyncToken::NoToken)).await.unwrap();
     server.reset().await;
 
     assert_eq!(room.avatar_url().as_deref(), Some(avatar_url_2));
diff --git a/crates/matrix-sdk/tests/integration/room/tags.rs b/crates/matrix-sdk/tests/integration/room/tags.rs
index 9d17a0cc555..8a50aca4ee6 100644
--- a/crates/matrix-sdk/tests/integration/room/tags.rs
+++ b/crates/matrix-sdk/tests/integration/room/tags.rs
@@ -1,6 +1,9 @@
 use std::{collections::BTreeMap, ops::Not, time::Duration};
 
-use matrix_sdk::{config::SyncSettings, Client, Room};
+use matrix_sdk::{
+    config::{SyncSettings, SyncToken},
+    Client, Room,
+};
 use matrix_sdk_test::{
     async_test, test_json, JoinedRoomBuilder, RoomAccountDataTestEvent, SyncResponseBuilder,
 };
@@ -61,7 +64,8 @@ async fn mock_sync_with_tags(
 }
 
 async fn sync_once(client: &Client, server: &MockServer) {
-    let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
+    let sync_settings =
+        SyncSettings::new().timeout(Duration::from_millis(3000)).token(SyncToken::NoToken);
     client.sync_once(sync_settings).await.unwrap();
     server.reset().await;
 }