diff --git a/changelog.d/7683.bugfix b/changelog.d/7683.bugfix
new file mode 100644
index 0000000000..3922253ba6
--- /dev/null
+++ b/changelog.d/7683.bugfix
@@ -0,0 +1,2 @@
+Fix crash in message composer when room is missing
+
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt
index a8be2be5e2..c02eb1fa8a 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt
@@ -59,6 +59,7 @@ import org.matrix.android.sdk.api.session.events.model.toContent
 import org.matrix.android.sdk.api.session.events.model.toModel
 import org.matrix.android.sdk.api.session.getRoom
 import org.matrix.android.sdk.api.session.getRoomSummary
+import org.matrix.android.sdk.api.session.room.Room
 import org.matrix.android.sdk.api.session.room.getStateEvent
 import org.matrix.android.sdk.api.session.room.getTimelineEvent
 import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
@@ -89,39 +90,44 @@ class MessageComposerViewModel @AssistedInject constructor(
         private val voiceBroadcastHelper: VoiceBroadcastHelper,
 ) : VectorViewModel<MessageComposerViewState, MessageComposerAction, MessageComposerViewEvents>(initialState) {
 
-    private val room = session.getRoom(initialState.roomId)!!
+    private val room = session.getRoom(initialState.roomId)
 
     // Keep it out of state to avoid invalidate being called
     private var currentComposerText: CharSequence = ""
 
     init {
-        loadDraftIfAny()
-        observePowerLevelAndEncryption()
-        observeVoiceBroadcast()
-        subscribeToStateInternal()
+        if (room != null) {
+            loadDraftIfAny(room)
+            observePowerLevelAndEncryption(room)
+            observeVoiceBroadcast(room)
+            subscribeToStateInternal()
+        } else {
+            onRoomError()
+        }
     }
 
     override fun handle(action: MessageComposerAction) {
+        val room = this.room ?: return
         when (action) {
-            is MessageComposerAction.EnterEditMode -> handleEnterEditMode(action)
-            is MessageComposerAction.EnterQuoteMode -> handleEnterQuoteMode(action)
+            is MessageComposerAction.EnterEditMode -> handleEnterEditMode(room, action)
+            is MessageComposerAction.EnterQuoteMode -> handleEnterQuoteMode(room, action)
             is MessageComposerAction.EnterRegularMode -> handleEnterRegularMode(action)
-            is MessageComposerAction.EnterReplyMode -> handleEnterReplyMode(action)
-            is MessageComposerAction.SendMessage -> handleSendMessage(action)
-            is MessageComposerAction.UserIsTyping -> handleUserIsTyping(action)
+            is MessageComposerAction.EnterReplyMode -> handleEnterReplyMode(room, action)
+            is MessageComposerAction.SendMessage -> handleSendMessage(room, action)
+            is MessageComposerAction.UserIsTyping -> handleUserIsTyping(room, action)
             is MessageComposerAction.OnTextChanged -> handleOnTextChanged(action)
             is MessageComposerAction.OnVoiceRecordingUiStateChanged -> handleOnVoiceRecordingUiStateChanged(action)
-            is MessageComposerAction.StartRecordingVoiceMessage -> handleStartRecordingVoiceMessage()
-            is MessageComposerAction.EndRecordingVoiceMessage -> handleEndRecordingVoiceMessage(action.isCancelled, action.rootThreadEventId)
+            is MessageComposerAction.StartRecordingVoiceMessage -> handleStartRecordingVoiceMessage(room)
+            is MessageComposerAction.EndRecordingVoiceMessage -> handleEndRecordingVoiceMessage(room, action.isCancelled, action.rootThreadEventId)
             is MessageComposerAction.PlayOrPauseVoicePlayback -> handlePlayOrPauseVoicePlayback(action)
             MessageComposerAction.PauseRecordingVoiceMessage -> handlePauseRecordingVoiceMessage()
             MessageComposerAction.PlayOrPauseRecordingPlayback -> handlePlayOrPauseRecordingPlayback()
-            is MessageComposerAction.InitializeVoiceRecorder -> handleInitializeVoiceRecorder(action.attachmentData)
-            is MessageComposerAction.OnEntersBackground -> handleEntersBackground(action.composerText)
+            is MessageComposerAction.InitializeVoiceRecorder -> handleInitializeVoiceRecorder(room, action.attachmentData)
+            is MessageComposerAction.OnEntersBackground -> handleEntersBackground(room, action.composerText)
             is MessageComposerAction.VoiceWaveformTouchedUp -> handleVoiceWaveformTouchedUp(action)
             is MessageComposerAction.VoiceWaveformMovedTo -> handleVoiceWaveformMovedTo(action)
             is MessageComposerAction.AudioSeekBarMovedTo -> handleAudioSeekBarMovedTo(action)
-            is MessageComposerAction.SlashCommandConfirmed -> handleSlashCommandConfirmed(action)
+            is MessageComposerAction.SlashCommandConfirmed -> handleSlashCommandConfirmed(room, action)
             is MessageComposerAction.InsertUserDisplayName -> handleInsertUserDisplayName(action)
             is MessageComposerAction.SetFullScreen -> handleSetFullScreen(action)
         }
@@ -157,7 +163,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         copy(sendMode = SendMode.Regular(currentComposerText, action.fromSharing))
     }
 
-    private fun handleEnterEditMode(action: MessageComposerAction.EnterEditMode) {
+    private fun handleEnterEditMode(room: Room, action: MessageComposerAction.EnterEditMode) {
         room.getTimelineEvent(action.eventId)?.let { timelineEvent ->
             val formatted = vectorPreferences.isRichTextEditorEnabled()
             setState { copy(sendMode = SendMode.Edit(timelineEvent, timelineEvent.getTextEditableContent(formatted))) }
@@ -168,7 +174,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         setState { copy(isFullScreen = action.isFullScreen) }
     }
 
-    private fun observePowerLevelAndEncryption() {
+    private fun observePowerLevelAndEncryption(room: Room) {
         combine(
                 PowerLevelsFlowFactory(room).createFlow(),
                 room.flow().liveRoomSummary().unwrap()
@@ -194,7 +200,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun observeVoiceBroadcast() {
+    private fun observeVoiceBroadcast(room: Room) {
         room.stateService().getStateEventLive(VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO, QueryStringValue.Equals(session.myUserId))
                 .asFlow()
                 .unwrap()
@@ -204,19 +210,19 @@ class MessageComposerViewModel @AssistedInject constructor(
                 }
     }
 
-    private fun handleEnterQuoteMode(action: MessageComposerAction.EnterQuoteMode) {
+    private fun handleEnterQuoteMode(room: Room, action: MessageComposerAction.EnterQuoteMode) {
         room.getTimelineEvent(action.eventId)?.let { timelineEvent ->
             setState { copy(sendMode = SendMode.Quote(timelineEvent, currentComposerText)) }
         }
     }
 
-    private fun handleEnterReplyMode(action: MessageComposerAction.EnterReplyMode) {
+    private fun handleEnterReplyMode(room: Room, action: MessageComposerAction.EnterReplyMode) {
         room.getTimelineEvent(action.eventId)?.let { timelineEvent ->
             setState { copy(sendMode = SendMode.Reply(timelineEvent, currentComposerText)) }
         }
     }
 
-    private fun handleSendMessage(action: MessageComposerAction.SendMessage) {
+    private fun handleSendMessage(room: Room, action: MessageComposerAction.SendMessage) {
         withState { state ->
             analyticsTracker.capture(state.toAnalyticsComposer()).also {
                 setState { copy(startsThread = false) }
@@ -246,7 +252,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                             }
 
                             _viewEvents.post(MessageComposerViewEvents.MessageSent)
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.ErrorSyntax -> {
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandError(parsedCommand.command))
@@ -272,7 +278,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                                 room.sendService().sendTextMessage(parsedCommand.message, autoMarkdown = false)
                             }
                             _viewEvents.post(MessageComposerViewEvents.MessageSent)
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.SendFormattedText -> {
                             // Send the text message to the room, without markdown
@@ -290,23 +296,23 @@ class MessageComposerViewModel @AssistedInject constructor(
                                 )
                             }
                             _viewEvents.post(MessageComposerViewEvents.MessageSent)
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.ChangeRoomName -> {
-                            handleChangeRoomNameSlashCommand(parsedCommand)
+                            handleChangeRoomNameSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.Invite -> {
-                            handleInviteSlashCommand(parsedCommand)
+                            handleInviteSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.Invite3Pid -> {
-                            handleInvite3pidSlashCommand(parsedCommand)
+                            handleInvite3pidSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.SetUserPowerLevel -> {
-                            handleSetUserPowerLevel(parsedCommand)
+                            handleSetUserPowerLevel(room, parsedCommand)
                         }
                         is ParsedCommand.DevTools -> {
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.ClearScalarToken -> {
                             // TODO
@@ -315,29 +321,29 @@ class MessageComposerViewModel @AssistedInject constructor(
                         is ParsedCommand.SetMarkdown -> {
                             vectorPreferences.setMarkdownEnabled(parsedCommand.enable)
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.BanUser -> {
-                            handleBanSlashCommand(parsedCommand)
+                            handleBanSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.UnbanUser -> {
-                            handleUnbanSlashCommand(parsedCommand)
+                            handleUnbanSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.IgnoreUser -> {
-                            handleIgnoreSlashCommand(parsedCommand)
+                            handleIgnoreSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.UnignoreUser -> {
                             handleUnignoreSlashCommand(parsedCommand)
                         }
                         is ParsedCommand.RemoveUser -> {
-                            handleRemoveSlashCommand(parsedCommand)
+                            handleRemoveSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.JoinRoom -> {
                             handleJoinToAnotherRoomSlashCommand(parsedCommand)
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.PartRoom -> {
-                            handlePartSlashCommand(parsedCommand)
+                            handlePartSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.SendEmote -> {
                             if (state.rootThreadEventId != null) {
@@ -355,7 +361,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                                 )
                             }
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.SendRainbow -> {
                             val message = parsedCommand.message.toString()
@@ -369,7 +375,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                                 room.sendService().sendFormattedTextMessage(message, rainbowGenerator.generate(message))
                             }
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.SendRainbowEmote -> {
                             val message = parsedCommand.message.toString()
@@ -385,7 +391,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                             }
 
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.SendSpoiler -> {
                             val text = "[${stringProvider.getString(R.string.spoiler)}](${parsedCommand.message})"
@@ -403,53 +409,53 @@ class MessageComposerViewModel @AssistedInject constructor(
                                 )
                             }
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.SendShrug -> {
-                            sendPrefixedMessage("¯\\_(ツ)_/¯", parsedCommand.message, state.rootThreadEventId)
+                            sendPrefixedMessage(room, "¯\\_(ツ)_/¯", parsedCommand.message, state.rootThreadEventId)
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.SendLenny -> {
-                            sendPrefixedMessage("( ͡° ͜ʖ ͡°)", parsedCommand.message, state.rootThreadEventId)
+                            sendPrefixedMessage(room, "( ͡° ͜ʖ ͡°)", parsedCommand.message, state.rootThreadEventId)
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.SendTableFlip -> {
-                            sendPrefixedMessage("(╯°□°)╯︵ ┻━┻", parsedCommand.message, state.rootThreadEventId)
+                            sendPrefixedMessage(room, "(╯°□°)╯︵ ┻━┻", parsedCommand.message, state.rootThreadEventId)
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.SendChatEffect -> {
-                            sendChatEffect(parsedCommand)
+                            sendChatEffect(room, parsedCommand)
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.ChangeTopic -> {
-                            handleChangeTopicSlashCommand(parsedCommand)
+                            handleChangeTopicSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.ChangeDisplayName -> {
-                            handleChangeDisplayNameSlashCommand(parsedCommand)
+                            handleChangeDisplayNameSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.ChangeDisplayNameForRoom -> {
-                            handleChangeDisplayNameForRoomSlashCommand(parsedCommand)
+                            handleChangeDisplayNameForRoomSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.ChangeRoomAvatar -> {
-                            handleChangeRoomAvatarSlashCommand(parsedCommand)
+                            handleChangeRoomAvatarSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.ChangeAvatarForRoom -> {
-                            handleChangeAvatarForRoomSlashCommand(parsedCommand)
+                            handleChangeAvatarForRoomSlashCommand(room, parsedCommand)
                         }
                         is ParsedCommand.ShowUser -> {
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
                             handleWhoisSlashCommand(parsedCommand)
-                            popDraft()
+                            popDraft(room)
                         }
                         is ParsedCommand.DiscardSession -> {
                             if (room.roomCryptoService().isEncrypted()) {
                                 session.cryptoService().discardOutboundSession(room.roomId)
                                 _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                                popDraft()
+                                popDraft(room)
                             } else {
                                 _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
                                 _viewEvents.post(
@@ -474,7 +480,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                                                     null,
                                                     true
                                             )
-                                    popDraft()
+                                    popDraft(room)
                                     _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
                                 } catch (failure: Throwable) {
                                     _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure))
@@ -493,7 +499,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                                                     null,
                                                     false
                                             )
-                                    popDraft()
+                                    popDraft(room)
                                     _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
                                 } catch (failure: Throwable) {
                                     _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure))
@@ -506,7 +512,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                             viewModelScope.launch(Dispatchers.IO) {
                                 try {
                                     session.spaceService().joinSpace(parsedCommand.spaceIdOrAlias)
-                                    popDraft()
+                                    popDraft(room)
                                     _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
                                 } catch (failure: Throwable) {
                                     _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure))
@@ -518,7 +524,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                             viewModelScope.launch(Dispatchers.IO) {
                                 try {
                                     session.roomService().leaveRoom(parsedCommand.roomId)
-                                    popDraft()
+                                    popDraft(room)
                                     _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
                                 } catch (failure: Throwable) {
                                     _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure))
@@ -534,7 +540,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                                     )
                             )
                             _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
-                            popDraft()
+                            popDraft(room)
                         }
                     }
                 }
@@ -583,7 +589,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                         }
                     }
                     _viewEvents.post(MessageComposerViewEvents.MessageSent)
-                    popDraft()
+                    popDraft(room)
                 }
                 is SendMode.Quote -> {
                     room.sendService().sendQuotedTextMessage(
@@ -594,7 +600,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                             rootThreadEventId = state.rootThreadEventId
                     )
                     _viewEvents.post(MessageComposerViewEvents.MessageSent)
-                    popDraft()
+                    popDraft(room)
                 }
                 is SendMode.Reply -> {
                     val timelineEvent = state.sendMode.timelineEvent
@@ -619,7 +625,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                     )
 
                     _viewEvents.post(MessageComposerViewEvents.MessageSent)
-                    popDraft()
+                    popDraft(room)
                 }
                 is SendMode.Voice -> {
                     // do nothing
@@ -628,10 +634,10 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun popDraft() = withState {
+    private fun popDraft(room: Room) = withState {
         if (it.sendMode is SendMode.Regular && it.sendMode.fromSharing) {
             // If we were sharing, we want to get back our last value from draft
-            loadDraftIfAny()
+            loadDraftIfAny(room)
         } else {
             // Otherwise we clear the composer and remove the draft from db
             setState { copy(sendMode = SendMode.Regular("", false)) }
@@ -641,7 +647,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun loadDraftIfAny() {
+    private fun loadDraftIfAny(room: Room) {
         val currentDraft = room.draftService().getDraft()
         setState {
             copy(
@@ -670,7 +676,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun handleUserIsTyping(action: MessageComposerAction.UserIsTyping) {
+    private fun handleUserIsTyping(room: Room, action: MessageComposerAction.UserIsTyping) {
         if (vectorPreferences.sendTypingNotifs()) {
             if (action.isTyping) {
                 room.typingService().userIsTyping()
@@ -680,7 +686,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun sendChatEffect(sendChatEffect: ParsedCommand.SendChatEffect) {
+    private fun sendChatEffect(room: Room, sendChatEffect: ParsedCommand.SendChatEffect) {
         // If message is blank, convert to an emote, with default message
         if (sendChatEffect.message.isBlank()) {
             val defaultMessage = stringProvider.getString(
@@ -732,25 +738,25 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun handleChangeTopicSlashCommand(changeTopic: ParsedCommand.ChangeTopic) {
-        launchSlashCommandFlowSuspendable(changeTopic) {
+    private fun handleChangeTopicSlashCommand(room: Room, changeTopic: ParsedCommand.ChangeTopic) {
+        launchSlashCommandFlowSuspendable(room, changeTopic) {
             room.stateService().updateTopic(changeTopic.topic)
         }
     }
 
-    private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) {
-        launchSlashCommandFlowSuspendable(invite) {
+    private fun handleInviteSlashCommand(room: Room, invite: ParsedCommand.Invite) {
+        launchSlashCommandFlowSuspendable(room, invite) {
             room.membershipService().invite(invite.userId, invite.reason)
         }
     }
 
-    private fun handleInvite3pidSlashCommand(invite: ParsedCommand.Invite3Pid) {
-        launchSlashCommandFlowSuspendable(invite) {
+    private fun handleInvite3pidSlashCommand(room: Room, invite: ParsedCommand.Invite3Pid) {
+        launchSlashCommandFlowSuspendable(room, invite) {
             room.membershipService().invite3pid(invite.threePid)
         }
     }
 
-    private fun handleSetUserPowerLevel(setUserPowerLevel: ParsedCommand.SetUserPowerLevel) {
+    private fun handleSetUserPowerLevel(room: Room, setUserPowerLevel: ParsedCommand.SetUserPowerLevel) {
         val newPowerLevelsContent = room.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
                 ?.content
                 ?.toModel<PowerLevelsContent>()
@@ -758,19 +764,19 @@ class MessageComposerViewModel @AssistedInject constructor(
                 ?.toContent()
                 ?: return
 
-        launchSlashCommandFlowSuspendable(setUserPowerLevel) {
+        launchSlashCommandFlowSuspendable(room, setUserPowerLevel) {
             room.stateService().sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent)
         }
     }
 
-    private fun handleChangeDisplayNameSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayName) {
-        launchSlashCommandFlowSuspendable(changeDisplayName) {
+    private fun handleChangeDisplayNameSlashCommand(room: Room, changeDisplayName: ParsedCommand.ChangeDisplayName) {
+        launchSlashCommandFlowSuspendable(room, changeDisplayName) {
             session.profileService().setDisplayName(session.myUserId, changeDisplayName.displayName)
         }
     }
 
-    private fun handlePartSlashCommand(command: ParsedCommand.PartRoom) {
-        launchSlashCommandFlowSuspendable(command) {
+    private fun handlePartSlashCommand(room: Room, command: ParsedCommand.PartRoom) {
+        launchSlashCommandFlowSuspendable(room, command) {
             if (command.roomAlias == null) {
                 // Leave the current room
                 room
@@ -785,39 +791,39 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun handleRemoveSlashCommand(removeUser: ParsedCommand.RemoveUser) {
-        launchSlashCommandFlowSuspendable(removeUser) {
+    private fun handleRemoveSlashCommand(room: Room, removeUser: ParsedCommand.RemoveUser) {
+        launchSlashCommandFlowSuspendable(room, removeUser) {
             room.membershipService().remove(removeUser.userId, removeUser.reason)
         }
     }
 
-    private fun handleBanSlashCommand(ban: ParsedCommand.BanUser) {
-        launchSlashCommandFlowSuspendable(ban) {
+    private fun handleBanSlashCommand(room: Room, ban: ParsedCommand.BanUser) {
+        launchSlashCommandFlowSuspendable(room, ban) {
             room.membershipService().ban(ban.userId, ban.reason)
         }
     }
 
-    private fun handleUnbanSlashCommand(unban: ParsedCommand.UnbanUser) {
-        launchSlashCommandFlowSuspendable(unban) {
+    private fun handleUnbanSlashCommand(room: Room, unban: ParsedCommand.UnbanUser) {
+        launchSlashCommandFlowSuspendable(room, unban) {
             room.membershipService().unban(unban.userId, unban.reason)
         }
     }
 
-    private fun handleChangeRoomNameSlashCommand(changeRoomName: ParsedCommand.ChangeRoomName) {
-        launchSlashCommandFlowSuspendable(changeRoomName) {
+    private fun handleChangeRoomNameSlashCommand(room: Room, changeRoomName: ParsedCommand.ChangeRoomName) {
+        launchSlashCommandFlowSuspendable(room, changeRoomName) {
             room.stateService().updateName(changeRoomName.name)
         }
     }
 
-    private fun getMyRoomMemberContent(): RoomMemberContent? {
+    private fun getMyRoomMemberContent(room: Room): RoomMemberContent? {
         return room.getStateEvent(EventType.STATE_ROOM_MEMBER, QueryStringValue.Equals(session.myUserId))
                 ?.content
                 ?.toModel<RoomMemberContent>()
     }
 
-    private fun handleChangeDisplayNameForRoomSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayNameForRoom) {
-        launchSlashCommandFlowSuspendable(changeDisplayName) {
-            getMyRoomMemberContent()
+    private fun handleChangeDisplayNameForRoomSlashCommand(room: Room, changeDisplayName: ParsedCommand.ChangeDisplayNameForRoom) {
+        launchSlashCommandFlowSuspendable(room, changeDisplayName) {
+            getMyRoomMemberContent(room)
                     ?.copy(displayName = changeDisplayName.displayName)
                     ?.toContent()
                     ?.let {
@@ -826,15 +832,15 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun handleChangeRoomAvatarSlashCommand(changeAvatar: ParsedCommand.ChangeRoomAvatar) {
-        launchSlashCommandFlowSuspendable(changeAvatar) {
+    private fun handleChangeRoomAvatarSlashCommand(room: Room, changeAvatar: ParsedCommand.ChangeRoomAvatar) {
+        launchSlashCommandFlowSuspendable(room, changeAvatar) {
             room.stateService().sendStateEvent(EventType.STATE_ROOM_AVATAR, stateKey = "", RoomAvatarContent(changeAvatar.url).toContent())
         }
     }
 
-    private fun handleChangeAvatarForRoomSlashCommand(changeAvatar: ParsedCommand.ChangeAvatarForRoom) {
-        launchSlashCommandFlowSuspendable(changeAvatar) {
-            getMyRoomMemberContent()
+    private fun handleChangeAvatarForRoomSlashCommand(room: Room, changeAvatar: ParsedCommand.ChangeAvatarForRoom) {
+        launchSlashCommandFlowSuspendable(room, changeAvatar) {
+            getMyRoomMemberContent(room)
                     ?.copy(avatarUrl = changeAvatar.url)
                     ?.toContent()
                     ?.let {
@@ -843,8 +849,8 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun handleIgnoreSlashCommand(ignore: ParsedCommand.IgnoreUser) {
-        launchSlashCommandFlowSuspendable(ignore) {
+    private fun handleIgnoreSlashCommand(room: Room, ignore: ParsedCommand.IgnoreUser) {
+        launchSlashCommandFlowSuspendable(room, ignore) {
             session.userService().ignoreUserIds(listOf(ignore.userId))
         }
     }
@@ -853,15 +859,15 @@ class MessageComposerViewModel @AssistedInject constructor(
         _viewEvents.post(MessageComposerViewEvents.SlashCommandConfirmationRequest(unignore))
     }
 
-    private fun handleSlashCommandConfirmed(action: MessageComposerAction.SlashCommandConfirmed) {
+    private fun handleSlashCommandConfirmed(room: Room, action: MessageComposerAction.SlashCommandConfirmed) {
         when (action.parsedCommand) {
-            is ParsedCommand.UnignoreUser -> handleUnignoreSlashCommandConfirmed(action.parsedCommand)
+            is ParsedCommand.UnignoreUser -> handleUnignoreSlashCommandConfirmed(room, action.parsedCommand)
             else -> TODO("Not handled yet")
         }
     }
 
-    private fun handleUnignoreSlashCommandConfirmed(unignore: ParsedCommand.UnignoreUser) {
-        launchSlashCommandFlowSuspendable(unignore) {
+    private fun handleUnignoreSlashCommandConfirmed(room: Room, unignore: ParsedCommand.UnignoreUser) {
+        launchSlashCommandFlowSuspendable(room, unignore) {
             session.userService().unIgnoreUserIds(listOf(unignore.userId))
         }
     }
@@ -870,7 +876,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         _viewEvents.post(MessageComposerViewEvents.OpenRoomMemberProfile(whois.userId))
     }
 
-    private fun sendPrefixedMessage(prefix: String, message: CharSequence, rootThreadEventId: String?) {
+    private fun sendPrefixedMessage(room: Room, prefix: String, message: CharSequence, rootThreadEventId: String?) {
         val sequence = buildString {
             append(prefix)
             if (message.isNotEmpty()) {
@@ -886,7 +892,7 @@ class MessageComposerViewModel @AssistedInject constructor(
     /**
      * Convert a send mode to a draft and save the draft.
      */
-    private fun handleSaveTextDraft(draft: String) = withState {
+    private fun handleSaveTextDraft(room: Room, draft: String) = withState {
         session.coroutineScope.launch {
             when {
                 it.sendMode is SendMode.Regular && !it.sendMode.fromSharing -> {
@@ -909,7 +915,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun handleStartRecordingVoiceMessage() {
+    private fun handleStartRecordingVoiceMessage(room: Room) {
         try {
             audioMessageHelper.startRecording(room.roomId)
         } catch (failure: Throwable) {
@@ -917,7 +923,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
-    private fun handleEndRecordingVoiceMessage(isCancelled: Boolean, rootThreadEventId: String? = null) {
+    private fun handleEndRecordingVoiceMessage(room: Room, isCancelled: Boolean, rootThreadEventId: String? = null) {
         audioMessageHelper.stopPlayback()
         if (isCancelled) {
             audioMessageHelper.deleteRecording()
@@ -964,7 +970,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         audioMessageHelper.stopAllVoiceActions(deleteRecord)
     }
 
-    private fun handleInitializeVoiceRecorder(attachmentData: ContentAttachmentData) {
+    private fun handleInitializeVoiceRecorder(room: Room, attachmentData: ContentAttachmentData) {
         audioMessageHelper.initializeRecorder(room.roomId, attachmentData)
         setState { copy(voiceRecordingUiState = VoiceMessageRecorderView.RecordingUiState.Draft) }
     }
@@ -985,7 +991,7 @@ class MessageComposerViewModel @AssistedInject constructor(
         audioMessageHelper.movePlaybackTo(action.eventId, action.percentage, action.duration)
     }
 
-    private fun handleEntersBackground(composerText: String) {
+    private fun handleEntersBackground(room: Room, composerText: String) {
         // Always stop all voice actions. It may be playing in timeline or active recording
         val playingAudioContent = audioMessageHelper.stopAllVoiceActions(deleteRecord = false)
         // TODO remove this when there will be a listening indicator outside of the timeline
@@ -1001,7 +1007,7 @@ class MessageComposerViewModel @AssistedInject constructor(
                 }
             }
         } else {
-            handleSaveTextDraft(draft = composerText)
+            handleSaveTextDraft(room = room, draft = composerText)
         }
     }
 
@@ -1009,12 +1015,12 @@ class MessageComposerViewModel @AssistedInject constructor(
         _viewEvents.post(MessageComposerViewEvents.InsertUserDisplayName(action.userId))
     }
 
-    private fun launchSlashCommandFlowSuspendable(parsedCommand: ParsedCommand, block: suspend () -> Unit) {
+    private fun launchSlashCommandFlowSuspendable(room: Room, parsedCommand: ParsedCommand, block: suspend () -> Unit) {
         _viewEvents.post(MessageComposerViewEvents.SlashCommandLoading)
         viewModelScope.launch {
             val event = try {
                 block()
-                popDraft()
+                popDraft(room)
                 MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)
             } catch (failure: Throwable) {
                 MessageComposerViewEvents.SlashCommandResultError(failure)
@@ -1023,6 +1029,10 @@ class MessageComposerViewModel @AssistedInject constructor(
         }
     }
 
+    private fun onRoomError() = setState {
+        copy(isRoomError = true)
+    }
+
     @AssistedFactory
     interface Factory : MavericksAssistedViewModelFactory<MessageComposerViewModel, MessageComposerViewState> {
         override fun create(initialState: MessageComposerViewState): MessageComposerViewModel
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewState.kt
index bf40c18995..235ca574fc 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewState.kt
@@ -62,6 +62,7 @@ fun CanSendStatus.boolean(): Boolean {
 
 data class MessageComposerViewState(
         val roomId: String,
+        val isRoomError: Boolean = false,
         val canSendMessage: CanSendStatus = CanSendStatus.Allowed,
         val isSendButtonVisible: Boolean = false,
         val rootThreadEventId: String? = null,
@@ -88,8 +89,8 @@ data class MessageComposerViewState(
 
     val isVoiceMessageIdle = !isVoiceRecording
 
-    val isComposerVisible = canSendMessage.boolean() && !isVoiceRecording
-    val isVoiceMessageRecorderVisible = canSendMessage.boolean() && !isSendButtonVisible
+    val isComposerVisible = canSendMessage.boolean() && !isVoiceRecording && !isRoomError
+    val isVoiceMessageRecorderVisible = canSendMessage.boolean() && !isSendButtonVisible && !isRoomError
 
     constructor(args: TimelineArgs) : this(
             roomId = args.roomId,