diff --git a/src/client_server/membership.rs b/src/client_server/membership.rs
index a9a5109a80a88031276a195b909e2a455c55f7cb..05501bdb459ed2e3b75c743c9da96beea09d5f2e 100644
--- a/src/client_server/membership.rs
+++ b/src/client_server/membership.rs
@@ -24,7 +24,7 @@
         room::{create::CreateEventContent, member},
         EventType,
     },
-    serde::{to_canonical_value, CanonicalJsonObject, Raw},
+    serde::{to_canonical_value, CanonicalJsonObject, CanonicalJsonValue, Raw},
     uint, EventId, RoomId, RoomVersionId, ServerName, UserId,
 };
 use state_res::EventMap;
@@ -481,13 +481,15 @@ async fn join_room_by_id_helper(
         // TODO: Is origin needed?
         join_event_stub.insert(
             "origin".to_owned(),
-            to_canonical_value(db.globals.server_name())
-                .map_err(|_| Error::bad_database("Invalid server name found"))?,
+            CanonicalJsonValue::String(db.globals.server_name().as_str().to_owned()),
         );
         join_event_stub.insert(
             "origin_server_ts".to_owned(),
-            to_canonical_value(utils::millis_since_unix_epoch())
-                .expect("Timestamp is valid js_int value"),
+            CanonicalJsonValue::Integer(
+                utils::millis_since_unix_epoch()
+                    .try_into()
+                    .expect("Timestamp is valid js_int value"),
+            ),
         );
         join_event_stub.insert(
             "content".to_owned(),
@@ -524,7 +526,7 @@ async fn join_room_by_id_helper(
         // Add event_id back
         join_event_stub.insert(
             "event_id".to_owned(),
-            to_canonical_value(&event_id).expect("EventId is a valid CanonicalJsonValue"),
+            CanonicalJsonValue::String(event_id.as_str().to_owned()),
         );
 
         // It has enough fields to be called a proper event now
@@ -717,8 +719,7 @@ async fn validate_and_add_event_id(
 
     value.insert(
         "event_id".to_owned(),
-        to_canonical_value(&event_id)
-            .expect("a valid EventId can be converted to CanonicalJsonValue"),
+        CanonicalJsonValue::String(event_id.as_str().to_owned()),
     );
 
     Ok((event_id, value))
diff --git a/src/database/rooms.rs b/src/database/rooms.rs
index 24ab65f3854882396856b8b079376871cfc688b8..7cee94401e5a981db7822e94f95295fdbd39b48c 100644
--- a/src/database/rooms.rs
+++ b/src/database/rooms.rs
@@ -15,7 +15,7 @@
         AnyStrippedStateEvent, AnySyncStateEvent, EventType,
     },
     push::{self, Action, Tweak},
-    serde::{to_canonical_value, CanonicalJsonObject, CanonicalJsonValue, Raw},
+    serde::{CanonicalJsonObject, CanonicalJsonValue, Raw},
     uint, EventId, RoomAliasId, RoomId, RoomVersionId, ServerName, UserId,
 };
 use sled::IVec;
@@ -372,9 +372,7 @@ pub fn force_state(
 
         for event_id in new_state.difference(&old_state) {
             if let Some(pdu) = self.get_pdu_json(event_id)? {
-                if pdu.get("event_type")
-                    == Some(&CanonicalJsonValue::String("m.room.member".to_owned()))
-                {
+                if pdu.get("event_type").and_then(|val| val.as_str()) == Some("m.room.member") {
                     if let Ok(pdu) = serde_json::from_value::<PduEvent>(
                         serde_json::to_value(&pdu).expect("CanonicalJsonObj is a valid JsonValue"),
                     ) {
@@ -1321,8 +1319,7 @@ pub fn build_and_append_pdu(
         // Add origin because synapse likes that (and it's required in the spec)
         pdu_json.insert(
             "origin".to_owned(),
-            to_canonical_value(db.globals.server_name())
-                .expect("server name is a valid CanonicalJsonValue"),
+            CanonicalJsonValue::String(db.globals.server_name().as_ref().to_owned()),
         );
 
         ruma::signatures::hash_and_sign_event(
@@ -1343,7 +1340,7 @@ pub fn build_and_append_pdu(
 
         pdu_json.insert(
             "event_id".to_owned(),
-            to_canonical_value(&pdu.event_id).expect("EventId is a valid CanonicalJsonValue"),
+            CanonicalJsonValue::String(pdu.event_id.as_str().to_owned()),
         );
 
         // Increment the last index and use that
@@ -1885,13 +1882,15 @@ async fn remote_leave_room(
         // TODO: Is origin needed?
         leave_event_stub.insert(
             "origin".to_owned(),
-            to_canonical_value(db.globals.server_name())
-                .map_err(|_| Error::bad_database("Invalid server name found"))?,
+            CanonicalJsonValue::String(db.globals.server_name().as_str().to_owned()),
         );
         leave_event_stub.insert(
             "origin_server_ts".to_owned(),
-            to_canonical_value(utils::millis_since_unix_epoch())
-                .expect("Timestamp is valid js_int value"),
+            CanonicalJsonValue::Integer(
+                utils::millis_since_unix_epoch()
+                    .try_into()
+                    .expect("Timestamp is valid js_int value"),
+            ),
         );
         // We don't leave the event id in the pdu because that's only allowed in v1 or v2 rooms
         leave_event_stub.remove("event_id");
@@ -1916,7 +1915,7 @@ async fn remote_leave_room(
         // Add event_id back
         leave_event_stub.insert(
             "event_id".to_owned(),
-            to_canonical_value(&event_id).expect("EventId is a valid CanonicalJsonValue"),
+            CanonicalJsonValue::String(event_id.as_str().to_owned()),
         );
 
         // It has enough fields to be called a proper event now
diff --git a/src/pdu.rs b/src/pdu.rs
index a7d9432858a79a2c0630029a84b5c05bb6bd024b..d66247f7848b52f15be4936edfc93e82c5ac6c67 100644
--- a/src/pdu.rs
+++ b/src/pdu.rs
@@ -5,7 +5,7 @@
         pdu::EventHash, room::member::MemberEventContent, AnyEvent, AnyRoomEvent, AnyStateEvent,
         AnyStrippedStateEvent, AnySyncRoomEvent, AnySyncStateEvent, EventType, StateEvent,
     },
-    serde::{to_canonical_value, CanonicalJsonObject, CanonicalJsonValue, Raw},
+    serde::{CanonicalJsonObject, CanonicalJsonValue, Raw},
     EventId, RoomId, RoomVersionId, ServerName, ServerSigningKeyId, UInt, UserId,
 };
 use serde::{Deserialize, Serialize};
@@ -238,7 +238,7 @@ pub fn from_id_val(
     ) -> Result<Self, serde_json::Error> {
         json.insert(
             "event_id".to_string(),
-            to_canonical_value(event_id).expect("event_id is a valid Value"),
+            CanonicalJsonValue::String(event_id.as_str().to_owned()),
         );
 
         serde_json::from_value(serde_json::to_value(json).expect("valid JSON"))
diff --git a/src/server_server.rs b/src/server_server.rs
index a6d58642055fa13f6f958a5b7666597b22f4f674..1e58067e9f92adffb3da27c67a7cb88e3b449b85 100644
--- a/src/server_server.rs
+++ b/src/server_server.rs
@@ -33,7 +33,7 @@
         },
         EventType,
     },
-    serde::{to_canonical_value, Raw},
+    serde::Raw,
     signatures::{CanonicalJsonObject, CanonicalJsonValue},
     uint, EventId, RoomId, RoomVersionId, ServerName, ServerSigningKeyId, UserId,
 };
@@ -709,11 +709,7 @@ pub fn handle_incoming_pdu<'a>(
         // 1. Check the server is in the room
         let room_id = match value
             .get("room_id")
-            .map(|id| match id {
-                CanonicalJsonValue::String(id) => RoomId::try_from(id.as_str()).ok(),
-                _ => None,
-            })
-            .flatten()
+            .and_then(|id| RoomId::try_from(id.as_str()?).ok())
         {
             Some(id) => id,
             None => {
@@ -776,7 +772,7 @@ pub fn handle_incoming_pdu<'a>(
         // to our PduEvent type
         val.insert(
             "event_id".to_owned(),
-            to_canonical_value(&event_id).expect("EventId is a valid CanonicalJsonValue"),
+            CanonicalJsonValue::String(event_id.as_str().to_owned()),
         );
         let incoming_pdu = serde_json::from_value::<PduEvent>(
             serde_json::to_value(&val).expect("CanonicalJsonObj is a valid JsonValue"),
@@ -1306,8 +1302,7 @@ pub(crate) fn fetch_and_handle_events<'a>(
                                     Ok(_) => {
                                         value.insert(
                                             "event_id".to_owned(),
-                                            to_canonical_value(&event_id)
-                                                .expect("EventId is a valid CanonicalJsonValue"),
+                                            CanonicalJsonValue::String(event_id.into()),
                                         );
 
                                         Arc::new(serde_json::from_value(
@@ -1805,8 +1800,7 @@ pub fn create_join_event_template_route<'a>(
     // Add origin because synapse likes that (and it's required in the spec)
     pdu_json.insert(
         "origin".to_owned(),
-        to_canonical_value(db.globals.server_name())
-            .expect("server name is a valid CanonicalJsonValue"),
+        CanonicalJsonValue::String(db.globals.server_name().as_str().to_owned()),
     );
 
     Ok(create_join_event_template::v1::Response {
@@ -1979,33 +1973,30 @@ pub async fn create_invite_route<'a>(
     // Add event_id back
     signed_event.insert(
         "event_id".to_owned(),
-        to_canonical_value(&event_id).expect("EventId is a valid CanonicalJsonValue"),
+        CanonicalJsonValue::String(event_id.into()),
     );
 
     let sender = serde_json::from_value(
-        serde_json::to_value(
-            signed_event
-                .get("sender")
-                .ok_or(Error::BadRequest(
-                    ErrorKind::InvalidParam,
-                    "Event had no sender field.",
-                ))?
-                .clone(),
-        )
-        .expect("CanonicalJsonValue to serde_json::Value always works"),
+        signed_event
+            .get("sender")
+            .ok_or(Error::BadRequest(
+                ErrorKind::InvalidParam,
+                "Event had no sender field.",
+            ))?
+            .clone()
+            .into(),
     )
     .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "sender is not a user id."))?;
+
     let invited_user = serde_json::from_value(
-        serde_json::to_value(
-            signed_event
-                .get("state_key")
-                .ok_or(Error::BadRequest(
-                    ErrorKind::InvalidParam,
-                    "Event had no state_key field.",
-                ))?
-                .clone(),
-        )
-        .expect("CanonicalJsonValue to serde_json::Value always works"),
+        signed_event
+            .get("state_key")
+            .ok_or(Error::BadRequest(
+                ErrorKind::InvalidParam,
+                "Event had no state_key field.",
+            ))?
+            .clone()
+            .into(),
     )
     .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "state_key is not a user id."))?;
 
@@ -2150,39 +2141,36 @@ pub async fn fetch_required_signing_keys(
     pub_key_map: &RwLock<BTreeMap<String, BTreeMap<String, String>>>,
     db: &Database,
 ) -> Result<()> {
+    let signatures = event
+        .get("signatures")
+        .ok_or(Error::BadServerResponse(
+            "No signatures in server response pdu.",
+        ))?
+        .as_object()
+        .ok_or(Error::BadServerResponse(
+            "Invalid signatures object in server response pdu.",
+        ))?;
+
     // We go through all the signatures we see on the value and fetch the corresponding signing
     // keys
-    for (signature_server, signature) in match event.get("signatures").ok_or(
-        Error::BadServerResponse("No signatures in server response pdu."),
-    )? {
-        CanonicalJsonValue::Object(map) => map,
-        _ => {
-            return Err(Error::BadServerResponse(
-                "Invalid signatures object in server response pdu.",
-            ))
-        }
-    } {
-        let signature_object = match signature {
-            CanonicalJsonValue::Object(map) => map,
-            _ => {
-                return Err(Error::BadServerResponse(
-                    "Invalid signatures content object in server response pdu.",
-                ))
-            }
-        };
+    for (signature_server, signature) in signatures {
+        let signature_object = signature.as_object().ok_or(Error::BadServerResponse(
+            "Invalid signatures content object in server response pdu.",
+        ))?;
 
         let signature_ids = signature_object.keys().collect::<Vec<_>>();
 
         debug!("Fetching signing keys for {}", signature_server);
-        let keys = match fetch_signing_keys(
+        let fetch_res = fetch_signing_keys(
             db,
             &Box::<ServerName>::try_from(&**signature_server).map_err(|_| {
                 Error::BadServerResponse("Invalid servername in signatures of server response pdu.")
             })?,
             signature_ids,
         )
-        .await
-        {
+        .await;
+
+        let keys = match fetch_res {
             Ok(keys) => keys,
             Err(_) => {
                 warn!("Signature verification failed: Could not fetch signing key.",);