marimo
marimo copied to clipboard
marimo.toml configuration overwritten by UI user setting change
Describe the bug
When I edit the user setting in the browser UI, the .marimo.toml file is overwritten and all the settings that existed previously in .marimo.toml are lost.
Steps to reproduce:
Create project
uv init
uv add marimo
touch .marimo.toml
echo "[runtime]" >> .marimo.toml
echo 'dotenv = [".env.dev"]' >> .marimo.toml
touch .env.dev
echo "TEST=TEST_VAR" >> .env.dev
Config file contents
pyprojectfile
cat pyproject.toml
[project]
name = "marimo-bug"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
"marimo>=0.17.8",
]
marimo.toml
cat .marimo.toml
[runtime]
dotenv = [".env.dev"]
Config
uv run marimo config show
📁 Project overrides from /home/marimo-bug/pyproject.toml
[runtime]
dotenv = []
🏠 User config from /home/marimo-bug/.marimo.toml
[package_management]
manager = "uv"
[keymap]
preset = "default"
[keymap.overrides]
[server]
browser = "default"
follow_symlink = false
[language_servers.pylsp]
enabled = false
enable_mypy = true
enable_ruff = true
enable_flake8 = false
enable_pydocstyle = false
enable_pylint = false
enable_pyflakes = false
[diagnostics]
sql_linter = true
[mcp]
presets = []
[mcp.mcpServers]
[completion]
activate_on_typing = true
copilot = false
[save]
autosave = "after_delay"
autosave_delay = 1000
format_on_save = false
[runtime]
on_cell_change = "autorun"
watcher_on_save = "lazy"
reactive_tests = true
auto_reload = "off"
dotenv = []
default_sql_output = "auto"
auto_instantiate = false
std_stream_max_bytes = 1000000
output_max_bytes = 8000000
[ai.models]
displayed_models = []
custom_models = []
[snippets]
custom_paths = []
include_default_snippets = true
[formatting]
line_length = 79
[display]
theme = "light"
code_editor_font_size = 14
cell_output = "below"
default_width = "medium"
dataframes = "rich"
default_table_page_size = 10
default_table_max_columns = 50
reference_highlighting = false
It correctly Identifies there is a .marimo.toml configuration file in the project root.
See how the dotenv is empty in the marimo config show output. Versus the actual file content.
Run the notebook
uv run marimo -d edit
The config file used is the one on project root.
INFO: Started server process [2529149]
INFO: Waiting for application startup.
[D 251114 07:22:25 lifespans:44] Setup: lsp
[D 251114 07:22:25 manager:441] Using config at /home/marimo-bug/.marimo.toml
[D 251114 07:22:25 lifespans:44] Setup: mcp
[D 251114 07:22:25 manager:441] Using config at /home/marimo-bug/.marimo.toml
The configuration is not picked up by the notebook
When trying to add a Secret the default .env is used not the .marimo.toml (.env.dev) setting.
Change any User setting in the UI
Logs:
[I 251114 07:33:39 manager:399] Saving user configuration to /home/marimo-bug/.marimo.toml
[D 251114 07:33:39 manager:441] Using config at /home/marimo-bug/.marimo.toml
This action overwrites the .marimo.toml file:
cat .marimo.toml
[completion]
copilot = false
activate_on_typing = true
[package_management]
manager = "uv"
[diagnostics]
sql_linter = true
[ai]
rules = ""
inline_tooltip = false
mode = "manual"
[ai.models]
displayed_models = []
custom_models = []
[mcp]
presets = []
[mcp.mcpServers]
[save]
format_on_save = false
autosave = "off"
autosave_delay = 1000
[experimental]
[server]
browser = "default"
follow_symlink = false
[display]
default_table_page_size = 10
reference_highlighting = false
dataframes = "rich"
default_width = "medium"
theme = "light"
code_editor_font_size = 14
default_table_max_columns = 50
cell_output = "below"
[keymap]
preset = "default"
destructive_delete = true
[keymap.overrides]
[runtime]
auto_reload = "off"
default_auto_download = []
std_stream_max_bytes = 1000000
watcher_on_save = "lazy"
on_cell_change = "autorun"
reactive_tests = true
auto_instantiate = false
output_max_bytes = 8000000
dotenv = []
default_sql_output = "auto"
[formatting]
line_length = 79
[snippets]
include_default_snippets = true
custom_paths = []
[language_servers.pylsp]
enable_ruff = true
enable_pylint = false
enable_pydocstyle = false
enable_flake8 = false
enable_pyflakes = false
enabled = false
enable_mypy = true
[language_servers.basedpyright]
[language_servers.ty]
pyproject stays the same
cat pyproject.toml
[project]
name = "marimo-bug"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
"marimo>=0.17.8",
]
The overwrite changed the runtime.dotenv parameter. Now it is not even possible to add a secret to the default .env file.
Will you submit a PR?
- [ ] Yes
Environment
{
"marimo": "0.17.8",
"editable": false,
"location": "/home/marimo-bug/.venv/lib/python3.14/site-packages/marimo",
"OS": "Linux",
"OS Version": "4.18.0-425.3.1.el8.x86_64",
"Processor": "x86_64",
"Python Version": "3.14.0",
"Locale": "en_US",
"Binaries": {
"Browser": "140.0.7339.185",
"Node": "--"
},
"Dependencies": {
"click": "8.3.0",
"docutils": "0.22.3",
"itsdangerous": "2.2.0",
"jedi": "0.19.2",
"markdown": "3.10",
"narwhals": "2.11.0",
"packaging": "25.0",
"psutil": "7.1.3",
"pygments": "2.19.2",
"pymdown-extensions": "10.17.1",
"pyyaml": "6.0.3",
"starlette": "0.50.0",
"tomlkit": "0.13.3",
"typing-extensions": "missing",
"uvicorn": "0.38.0",
"websockets": "15.0.1"
},
"Optional Dependencies": {},
"Experimental Flags": {}
}
Code to reproduce
import marimo
__generated_with = "0.17.8"
app = marimo.App(width="medium")
@app.cell
def _():
import marimo as mo
return
@app.cell
def _():
import os
return (os,)
@app.cell
def _(os):
os.environ["TEST"]
return
@app.cell
def _():
return
if __name__ == "__main__":
app.run()
marimo.toml is the "user" config. the editor UI edits the marimo.toml.
The pyproject.toml is not currently editable in the UI. If you have project specific settings, we recommend putting them in the pyproject.toml under [tool.marimo].
Im sure this is confusing, what thoughts do you have to make this more clear?
The
pyproject.tomlis not currently editable in the UI. If you have project-specific settings, we recommend putting them in thepyproject.tomlunder[tool.marimo].
This is clear and expected. I included the pyproject.toml content to prove that the issue comes from marimo.toml
marimo.tomlis the "user" config. The editor UI edits themarimo.toml.
This is clear from the documentation. However, marimo.toml is not edited - it is owewritten. My point is that on a UI edit, you lose all the user settings set up previously.
In the example above, the runtime.dotenv setting that was set up in marimo.toml is lost after a UI edit.
I would expect that any setting that exists in marimo.toml stays the same after the edit of a different setting.
Oh I missed that from the issue description. That does seem incorrect. We will definitely look into this.
In the meantime, does writing these sort of configs to the pyproject make sense? Was something preventing you from doing that (eg technical or use-case) that we can improve?
I think that .marimo.toml takes priority over pyproject, so adding the section to pyproject does not resolve the issue.
Testing the following flow:
- Added the section to pyproject.toml
[tool.marimo.runtime]
dotenv = [".env"]
- Edited the setting in the UI -> now .marimo.toml does not have the
runtime.dotenvsetting - Refresh the page
The dotenv location disappeared from the Add Secret window. My guess - the setting from .marimo.toml takes precedence over pyproject.toml
Update: If I restart the kernel, the setting is correctly applied -> from pyproject.
Looks like the issue only persists in the running kernel after a User settings change.