39 Downloads
39 Downloads
README
README
This Plugin - GitHub - Explicit | LMStudio
Original Plugin (model behavior dependent) - GitHub - Original | LMStudio
Optional Companion Plugin - GitHub - Context Cleanup | LMStudio
Persisting Memories Plugin Explicit is an LM Studio plugin that lets users preserve selected assistant responses as reusable memory seeds and inject those memories into future conversations. It stores memories as local JSON files, organizes them by category, and uses prompt preprocessing to add selected memories to the active prompt when needed.
Tested working on Windows 11 Pro 25H2 - LM Studio 0.4.24
New functions are now handled explicitly by the backend
I was in the process of making a compact a summary plugin that would automatically compact/summarize a chat session after a certain threshold was met but I found unreliableness from the model to prepare jsons that accurately summarized the entire chat being stashed and truncated, I dislike unreliableness so I put the idea on hiatus for now. Maybe I'll come to terms with it eventually. Long story short, I decided to bring some of those ideas to this persisting memories plugin. If you think about it my persisting memories plugin and context cleanup paired together somewhat achieves the same concept. The real difference is that it's not automatic, you have to "summarize" yourself by saving the memory seeds you deemed important, choose which seeds to inject, and configure the truncation with my context cleanup.
In my opinion though the explicit version is far better. Even with the 2 second inherient window required after the assistant finishes it's response. Even if you conflict with the time window, nothing will break — the backend would still function and correct itself. If the message number failed to append, you can guess which one it was based off the order of the successful message # appended. The other option before this final choice was I experimented with predictionLoopHandler but that ended in failure because it basically overtakes the entire default structure of how LM Studio chat behaves, which was a negative for broad compatibility.
This project gives LM Studio conversations a lightweight persistent memory layer. Instead of manually copying useful answers, users can select important assistant responses, save them as memory seeds, and later choose which memories should influence a new conversation.
A memory seed captures:
The plugin keeps the available memory pool in memory, injects selected memories into prompts, and can remove previously injected memories from the stored conversation file when the user no longer wants them. Plugin only refreshes at initialization or reconnection. If you added the memory through the chat it's immediately available even if you don't see it in the plugin's "Available Memory" yet.
From LM Studio Website: Install from the LM Studio Hub then enable the plugin.
From GitHub Source Code: Open PowerShell/terminal, navigate to root folder of the plugin you downloaded where you see the README, package, and manifest. Enter lms dev -i -y. Plugin should now be available in LM Studio.
To use, while the plugin is enabled, type to the model: "save memory <message #>; category <category_name>; name <memory_name>". (example: save memory 4; category cats; name some_information). save memory message # also works. If you forget the category or name, the model should ask for it before running the tool. The plugin will ask the model to visually identify each message # with you — just base your # provided off what you're shown.

Through the use of prompt preprocessing, the memory seed is injected alongside the user's message on the newest user's turn.
The added text will now be able to be referenced by the assistant.


Removing and deleting are two distinct actions. Remove means your intention is to remove the memory from the current chat session's context. Deleting means you wish to permanently discard the memory — there is no backup/undo.

| Field | Purpose |
|---|---|
| Delete Memory | Full name of the memory to delete. Deletion is permanent. Bubbles will not update until reinitialization — this is a UI limitation of LM Studio. |
| Available Memories | Display-only: a list of available memories. Users can copy names from this list into Memories to Inject or Delete Memory. |
| Memories to Inject | Memories that should be injected into the current session. Only the listed memories persist through turns. |

While enabled, the plugin will append a message # after each of the assistant's responses. This numbering makes it easier for users to refer to a specific exchange when asking to save a memory. If a message # failed to append, the message can still be chosen by the save memory command — just best-guess which message # it is based off the ordering of successful message #s appended onto other messages.
Save memory regex patterns (Example: svmem4 will be accepted and so will with store mmry msg4. the category is apple). Batch memory save requires a variation of through/to as a trigger and ending message number

This Plugin - GitHub - Explicit | LMStudio
Original Plugin (model behavior dependent) - GitHub - Original | LMStudio
Optional Companion Plugin - GitHub - Context Cleanup | LMStudio
Persisting Memories Plugin Explicit is an LM Studio plugin that lets users preserve selected assistant responses as reusable memory seeds and inject those memories into future conversations. It stores memories as local JSON files, organizes them by category, and uses prompt preprocessing to add selected memories to the active prompt when needed.
Tested working on Windows 11 Pro 25H2 - LM Studio 0.4.24
New functions are now handled explicitly by the backend
I was in the process of making a compact a summary plugin that would automatically compact/summarize a chat session after a certain threshold was met but I found unreliableness from the model to prepare jsons that accurately summarized the entire chat being stashed and truncated, I dislike unreliableness so I put the idea on hiatus for now. Maybe I'll come to terms with it eventually. Long story short, I decided to bring some of those ideas to this persisting memories plugin. If you think about it my persisting memories plugin and context cleanup paired together somewhat achieves the same concept. The real difference is that it's not automatic, you have to "summarize" yourself by saving the memory seeds you deemed important, choose which seeds to inject, and configure the truncation with my context cleanup.
In my opinion though the explicit version is far better. Even with the 2 second inherient window required after the assistant finishes it's response. Even if you conflict with the time window, nothing will break — the backend would still function and correct itself. If the message number failed to append, you can guess which one it was based off the order of the successful message # appended. The other option before this final choice was I experimented with predictionLoopHandler but that ended in failure because it basically overtakes the entire default structure of how LM Studio chat behaves, which was a negative for broad compatibility.
This project gives LM Studio conversations a lightweight persistent memory layer. Instead of manually copying useful answers, users can select important assistant responses, save them as memory seeds, and later choose which memories should influence a new conversation.
A memory seed captures:
The plugin keeps the available memory pool in memory, injects selected memories into prompts, and can remove previously injected memories from the stored conversation file when the user no longer wants them. Plugin only refreshes at initialization or reconnection. If you added the memory through the chat it's immediately available even if you don't see it in the plugin's "Available Memory" yet.
From LM Studio Website: Install from the LM Studio Hub then enable the plugin.
From GitHub Source Code: Open PowerShell/terminal, navigate to root folder of the plugin you downloaded where you see the README, package, and manifest. Enter lms dev -i -y. Plugin should now be available in LM Studio.
To use, while the plugin is enabled, type to the model: "save memory <message #>; category <category_name>; name <memory_name>". (example: save memory 4; category cats; name some_information). save memory message # also works. If you forget the category or name, the model should ask for it before running the tool. The plugin will ask the model to visually identify each message # with you — just base your # provided off what you're shown.

Through the use of prompt preprocessing, the memory seed is injected alongside the user's message on the newest user's turn.
The added text will now be able to be referenced by the assistant.


Removing and deleting are two distinct actions. Remove means your intention is to remove the memory from the current chat session's context. Deleting means you wish to permanently discard the memory — there is no backup/undo.

| Field | Purpose |
|---|---|
| Delete Memory | Full name of the memory to delete. Deletion is permanent. Bubbles will not update until reinitialization — this is a UI limitation of LM Studio. |
| Available Memories | Display-only: a list of available memories. Users can copy names from this list into Memories to Inject or Delete Memory. |
| Memories to Inject | Memories that should be injected into the current session. Only the listed memories persist through turns. |

While enabled, the plugin will append a message # after each of the assistant's responses. This numbering makes it easier for users to refer to a specific exchange when asking to save a memory. If a message # failed to append, the message can still be chosen by the save memory command — just best-guess which message # it is based off the ordering of successful message #s appended onto other messages.
Save memory regex patterns (Example: svmem4 will be accepted and so will with store mmry msg4. the category is apple). Batch memory save requires a variation of through/to as a trigger and ending message number

The user controls the memory seeds they save, which is sorted by the user's choice too. The table of memories, when first initialized, will send every memory file through the model to extract keywords and provide a summary that best defines the contents of that memory file. Those values will then be added to one of three table of memories files living in the ~\.lmstudio\memories folder.

!! IMPORTANT !! Users are expected to send a one time user message with "Initialize Table of Memories" toggled ON. You must only do this once. This will create the TOM files and populate their fields with your memories created by older versions of this plugin. After this one time run, you should leave the option toggled OFF. The reason why is because the process can be expensive depending on how many memory files you have. You do not want to be initializing all your memories every turn. You do not have to worry that in the future the TOM becomes outdated as you add brand new memories or update old memories. The TOM will be maintained with the recent additions to the backend logic even while the "Initialize Table of Memories" remains off. The toggle will remain for future versions because it can still serve as a function to fully repair your TOM if you suspect it to be missing, corrupted, or inaccurate.


As your memory files grow you may forget what's in them. Users can now ask the model to use the plugin to help recall, find, or remember a memory based off of your fuzzy memory. In the backend the model will be given a collection of keywords tied to a memory file provided by the TOM files and asked to choose the top 8 best matches compared to the query. Then the best keyword matching candidates pass along their summaries for the model to determine up to 3 best matches to return to the user. From there once you determined which memory you were looking for, you can inject the memory normally through the "Memories to Inject" field.

Another method to find your memories is to look at the table yourself. You can ask the assistant to look up, fetch, get the memories table. It technically should ask you to specify which table before actually fetching it, but some models might just make assumptions and grab any table. Your options are TOM_A-I, TOM_J-R, TOM_S-Z. All non-alphabet characters will be stored in TOM_S-Z. You do not have to type it exactly, a model "should" understand tomjr refers to TOM_J-R. Just rememeber doing so brings all entries of the TOM request into context, this can consume a large amount of your context window depending on how many unique memory files you have stored. I recommend leaving the tool table_of_memories_lookup OFF if you do not actively needed it. Handing a misbehaving model a tool could mean it spams it and gives you any excuse it wants to avoid accountability.

Added Summarize All Memories Injected feature. This will summarized/condense any future memories you inject (does not apply retroactively), rather than injecting the memory seed verbatum. Results may vary, all memory seeds in the same file will most likely be consolidated into one big narrative unless they're distinctly different. Regardless it should save some context window compared to the verbatum approach. Just consider the feature as "there if you want it" you may find it useful for your needs. The feature does cause a delay to process and formulate the summaries before it's injection so it is not as quick as injecting the memory seed verbatum.
"save memory #" (example: save memory 5; category recipes; name chicken thighs).Inject all memory files within that category folder with <category_folder>/*.json.
Users will not be allowed to create a fle named * or *.json to protect this feature. (memory/file names like few*many will be allowed)

User says: save memory #, category <category_name>, name <memory_name>
save memory message # works too.; or , or .category and/or name.Batch memory save. save memory <message #> to <message #>; category <category>; name <name>.
User messages that are just save memory commands will be filtered out and not saved to the file during the batch process.

If category and/or name are not provided during the initial user message, the user will be asked in the following assistant message.

To remove: Just press the X on the memory bubble under the Memories to Inject section. Memories not listed in Memories to Inject are either not in context or will be removed from context in the next turn.
To delete: Copy and paste the exact memory name into the Delete Memory text field. The full memory name includes the .json suffix like recipes/chicken_thighs.json. It should instantly delete the memory. The plugin will not update Available Memories unless it's reinitialized or reconnected. But for all purposes, the deleted memory is immediately no longer accepted by the backend logic.
To delete a whole category: <category_folder>/*.json. Be warned, the moment you complete that name to delete up to the last n of .json and it is a valid existing folder, it's gone, there is no recovery.

Multi-Edit Coordinator: This coordinator now oversees the write actions, so there are not multiple read/write actions repeated to fulfill one request at a time. Now that responsibilities were taken away from the model serving as the middleman, these things must be explicitly handled in the backend. I had to refactor a lot of existing code into functions usable by the coordinator, but it was better than rewriting all the logics from scratch. Trade-off: a little more obscurity in the flow of each function, but I did my best trying to communicate ambiguity with descriptive function names and comments left behind.
file_name-persisting-memories-final-write.ready is now a coordination file created within the conversation folder to let PM catch up to the CC plugin and take the lead at executing its functions first. Persisting Memories plugin creates the .ready; Context Cleanup is expected to remove it. There may be abandoned .ready leftover files if your model crashes — they're 0KB so they just exist without any actual content. You may want to manually clean up any abandoned .ready files if you wish they're no longer relevant. Putting an automatic cleaner in one of the plugins would be unnecessary overhead.
file_name.lock: Lock files were added for cross-plugin compatibility with my Context Cleanup tool. This counters race conditions while a conversation.json is being updated/modified (written) — the lock makes the loser wait for its turn while the winner gets priority to complete their task.
Removal polling: When triggering memory seed edits, appending message # to the assistant message, and save memory commands that are missing fields to be provided, polls the conversation file every 100ms or 500ms depending on the condition if the .lock file originated from another plugin or its own plugin. The more aggressive polling is when the .lock belonged to another plugin — this way this plugin can act quicker to an external .lock release.
A memories folder will be created at C:\Users\USERNAME\.lmstudio, and a .json file that retains the relationship between the chat session and its conversation file will be stored in C:\Users\USERNAME\.lmstudio\conversations.
Injection markers: Memories will be injected within blocks of BEGIN and END markers containing the memory seed category/memory_name. These markers allow for later removal of the memory.
Internal Chat ID: The preprocessor will append a one-time InternalChatID [ICID] to mark the chat session. This marker helps identify the session and tie it to the corresponding conversation file. I've added fail-safes to recover the [ICID] marker when users purposely or accidentally delete the user message which contained the tag.
Conversation mapping: The plugin stores a relationship file that maps internal chat IDs to conversation file names. It keeps only the newest 15 relationships. C:\Users\USERNAME\.lmstudio\conversations\ChatSessionConversationRelationship.json
LM Studio also reinitializes plugins whenever it decides to, so reliable long-term storage of variables in outer scopes is not fully reliable and just used temporarily for the turn or as long as they're available. That includes storing current values in the Config Schematics. When values are lost, the backend code will re-establish them when needed.
Path safety: Memory names are normalized, but not to correct misspellings. It's easiest to copy and paste the memory name from the list displayed in Available Memories into the text field of Memories to Inject.
In-memory pool: The available memory pool is kept in memory and updated when files are deleted. Plugin UI updates may be delayed because of LM Studio plugin behavior, but on the backend these values are properly updated.
I had only 3 options to fully execute this: rely on the unreliable model, modify the conversation.json real-time, or use predictionLoopHandler.
The multi-edit coordinator I created is a key part to this working with less overhead. Instead of independently executing individual write functions one by one with each one carrying sometimes duplicated overhead, the coordinator figures out which functions want to execute, gathers their parameters, and does it all in one chained action. I had to refactor a lot of existing code into functions usable by the coordinator, but it was better than rewriting all the logics all over again. Trade-off: a little more obscurity in the flow of each function, but I did my best trying to communicate ambiguity with descriptive function names and comments left behind.
The file lock I created is key to letting this plugin work with my other cleanup plugin. If other plugins utilize the same file locking mechanic, this would be compatible with those plugins too. The .ready file is also key to forcing Context Cleanup to give priority of execution to Persisting Memories — otherwise CC reaches the lock creation 5–8ms faster on my system which may cause bugs like cleaning up messages that were required for the memory creation/associations.
Why is there a toolsProvider.ts even if these explicit functions aren't handled by tools anymore? LM Studio did not give me a native way to poll changes real-time to the Delete Memory text field — promptPreprocessor is limited to when the user fires off a new user message so it doesn't work. The only way to achieve real-time variable monitoring was to keep the toolsProvider enabled and letting the memory deletion trigger logic exist there.
Injected context will be hidden from the user, but visible to the assistant. User can ask the assistant to read out the injected memory if you wish to see it.
LM Studio's SDK does not have full support to make this implementation easy. The methods chosen to accomplish this feature were mandatory during the time of creation of this plugin.
The plugin assumes LM Studio Windows 11 conversation files are accessible under the configured root directory at C:\Users\USERNAME\.lmstudio\conversations.
The Memory bubbles displayed on the plugin do not update real-time. Again, another limitation of LM Studio not giving a way to send updated data upstream back to the plugin UI. The memory bubbles will update when the tool reinitializes, so when it's left idle for awhile then interacted with, or if you click the trashcan "reset" button. There are already validation checks in the backend to prevent any bugs, so don't worry about it. If you choose memories that aren't available, nothing will happen. If you add, remove, or delete memories that aren't active or exist, nothing will break — it'll just be a visual bug of the UI that will refresh upon its next initialization.
The user controls the memory seeds they save, which is sorted by the user's choice too. The table of memories, when first initialized, will send every memory file through the model to extract keywords and provide a summary that best defines the contents of that memory file. Those values will then be added to one of three table of memories files living in the ~\.lmstudio\memories folder.

!! IMPORTANT !! Users are expected to send a one time user message with "Initialize Table of Memories" toggled ON. You must only do this once. This will create the TOM files and populate their fields with your memories created by older versions of this plugin. After this one time run, you should leave the option toggled OFF. The reason why is because the process can be expensive depending on how many memory files you have. You do not want to be initializing all your memories every turn. You do not have to worry that in the future the TOM becomes outdated as you add brand new memories or update old memories. The TOM will be maintained with the recent additions to the backend logic even while the "Initialize Table of Memories" remains off. The toggle will remain for future versions because it can still serve as a function to fully repair your TOM if you suspect it to be missing, corrupted, or inaccurate.


As your memory files grow you may forget what's in them. Users can now ask the model to use the plugin to help recall, find, or remember a memory based off of your fuzzy memory. In the backend the model will be given a collection of keywords tied to a memory file provided by the TOM files and asked to choose the top 8 best matches compared to the query. Then the best keyword matching candidates pass along their summaries for the model to determine up to 3 best matches to return to the user. From there once you determined which memory you were looking for, you can inject the memory normally through the "Memories to Inject" field.

Another method to find your memories is to look at the table yourself. You can ask the assistant to look up, fetch, get the memories table. It technically should ask you to specify which table before actually fetching it, but some models might just make assumptions and grab any table. Your options are TOM_A-I, TOM_J-R, TOM_S-Z. All non-alphabet characters will be stored in TOM_S-Z. You do not have to type it exactly, a model "should" understand tomjr refers to TOM_J-R. Just rememeber doing so brings all entries of the TOM request into context, this can consume a large amount of your context window depending on how many unique memory files you have stored. I recommend leaving the tool table_of_memories_lookup OFF if you do not actively needed it. Handing a misbehaving model a tool could mean it spams it and gives you any excuse it wants to avoid accountability.

Added Summarize All Memories Injected feature. This will summarized/condense any future memories you inject (does not apply retroactively), rather than injecting the memory seed verbatum. Results may vary, all memory seeds in the same file will most likely be consolidated into one big narrative unless they're distinctly different. Regardless it should save some context window compared to the verbatum approach. Just consider the feature as "there if you want it" you may find it useful for your needs. The feature does cause a delay to process and formulate the summaries before it's injection so it is not as quick as injecting the memory seed verbatum.
"save memory #" (example: save memory 5; category recipes; name chicken thighs).Inject all memory files within that category folder with <category_folder>/*.json.
Users will not be allowed to create a fle named * or *.json to protect this feature. (memory/file names like few*many will be allowed)

User says: save memory #, category <category_name>, name <memory_name>
save memory message # works too.; or , or .category and/or name.Batch memory save. save memory <message #> to <message #>; category <category>; name <name>.
User messages that are just save memory commands will be filtered out and not saved to the file during the batch process.

If category and/or name are not provided during the initial user message, the user will be asked in the following assistant message.

To remove: Just press the X on the memory bubble under the Memories to Inject section. Memories not listed in Memories to Inject are either not in context or will be removed from context in the next turn.
To delete: Copy and paste the exact memory name into the Delete Memory text field. The full memory name includes the .json suffix like recipes/chicken_thighs.json. It should instantly delete the memory. The plugin will not update Available Memories unless it's reinitialized or reconnected. But for all purposes, the deleted memory is immediately no longer accepted by the backend logic.
To delete a whole category: <category_folder>/*.json. Be warned, the moment you complete that name to delete up to the last n of .json and it is a valid existing folder, it's gone, there is no recovery.

Multi-Edit Coordinator: This coordinator now oversees the write actions, so there are not multiple read/write actions repeated to fulfill one request at a time. Now that responsibilities were taken away from the model serving as the middleman, these things must be explicitly handled in the backend. I had to refactor a lot of existing code into functions usable by the coordinator, but it was better than rewriting all the logics from scratch. Trade-off: a little more obscurity in the flow of each function, but I did my best trying to communicate ambiguity with descriptive function names and comments left behind.
file_name-persisting-memories-final-write.ready is now a coordination file created within the conversation folder to let PM catch up to the CC plugin and take the lead at executing its functions first. Persisting Memories plugin creates the .ready; Context Cleanup is expected to remove it. There may be abandoned .ready leftover files if your model crashes — they're 0KB so they just exist without any actual content. You may want to manually clean up any abandoned .ready files if you wish they're no longer relevant. Putting an automatic cleaner in one of the plugins would be unnecessary overhead.
file_name.lock: Lock files were added for cross-plugin compatibility with my Context Cleanup tool. This counters race conditions while a conversation.json is being updated/modified (written) — the lock makes the loser wait for its turn while the winner gets priority to complete their task.
Removal polling: When triggering memory seed edits, appending message # to the assistant message, and save memory commands that are missing fields to be provided, polls the conversation file every 100ms or 500ms depending on the condition if the .lock file originated from another plugin or its own plugin. The more aggressive polling is when the .lock belonged to another plugin — this way this plugin can act quicker to an external .lock release.
A memories folder will be created at C:\Users\USERNAME\.lmstudio, and a .json file that retains the relationship between the chat session and its conversation file will be stored in C:\Users\USERNAME\.lmstudio\conversations.
Injection markers: Memories will be injected within blocks of BEGIN and END markers containing the memory seed category/memory_name. These markers allow for later removal of the memory.
Internal Chat ID: The preprocessor will append a one-time InternalChatID [ICID] to mark the chat session. This marker helps identify the session and tie it to the corresponding conversation file. I've added fail-safes to recover the [ICID] marker when users purposely or accidentally delete the user message which contained the tag.
Conversation mapping: The plugin stores a relationship file that maps internal chat IDs to conversation file names. It keeps only the newest 15 relationships. C:\Users\USERNAME\.lmstudio\conversations\ChatSessionConversationRelationship.json
LM Studio also reinitializes plugins whenever it decides to, so reliable long-term storage of variables in outer scopes is not fully reliable and just used temporarily for the turn or as long as they're available. That includes storing current values in the Config Schematics. When values are lost, the backend code will re-establish them when needed.
Path safety: Memory names are normalized, but not to correct misspellings. It's easiest to copy and paste the memory name from the list displayed in Available Memories into the text field of Memories to Inject.
In-memory pool: The available memory pool is kept in memory and updated when files are deleted. Plugin UI updates may be delayed because of LM Studio plugin behavior, but on the backend these values are properly updated.
I had only 3 options to fully execute this: rely on the unreliable model, modify the conversation.json real-time, or use predictionLoopHandler.
The multi-edit coordinator I created is a key part to this working with less overhead. Instead of independently executing individual write functions one by one with each one carrying sometimes duplicated overhead, the coordinator figures out which functions want to execute, gathers their parameters, and does it all in one chained action. I had to refactor a lot of existing code into functions usable by the coordinator, but it was better than rewriting all the logics all over again. Trade-off: a little more obscurity in the flow of each function, but I did my best trying to communicate ambiguity with descriptive function names and comments left behind.
The file lock I created is key to letting this plugin work with my other cleanup plugin. If other plugins utilize the same file locking mechanic, this would be compatible with those plugins too. The .ready file is also key to forcing Context Cleanup to give priority of execution to Persisting Memories — otherwise CC reaches the lock creation 5–8ms faster on my system which may cause bugs like cleaning up messages that were required for the memory creation/associations.
Why is there a toolsProvider.ts even if these explicit functions aren't handled by tools anymore? LM Studio did not give me a native way to poll changes real-time to the Delete Memory text field — promptPreprocessor is limited to when the user fires off a new user message so it doesn't work. The only way to achieve real-time variable monitoring was to keep the toolsProvider enabled and letting the memory deletion trigger logic exist there.
Injected context will be hidden from the user, but visible to the assistant. User can ask the assistant to read out the injected memory if you wish to see it.
LM Studio's SDK does not have full support to make this implementation easy. The methods chosen to accomplish this feature were mandatory during the time of creation of this plugin.
The plugin assumes LM Studio Windows 11 conversation files are accessible under the configured root directory at C:\Users\USERNAME\.lmstudio\conversations.
The Memory bubbles displayed on the plugin do not update real-time. Again, another limitation of LM Studio not giving a way to send updated data upstream back to the plugin UI. The memory bubbles will update when the tool reinitializes, so when it's left idle for awhile then interacted with, or if you click the trashcan "reset" button. There are already validation checks in the backend to prevent any bugs, so don't worry about it. If you choose memories that aren't available, nothing will happen. If you add, remove, or delete memories that aren't active or exist, nothing will break — it'll just be a visual bug of the UI that will refresh upon its next initialization.