marimo icon indicating copy to clipboard operation
marimo copied to clipboard

marimo.toml configuration overwritten by UI user setting change

Open dimitsqx opened this issue 3 weeks ago • 5 comments

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. Image

Change any User setting in the UI

Image

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.

Image

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()

dimitsqx avatar Nov 14 '25 12:11 dimitsqx

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?

mscolnick avatar Nov 14 '25 17:11 mscolnick

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].

This is clear and expected. I included the pyproject.toml content to prove that the issue comes from marimo.toml

marimo.toml is the "user" config. The editor UI edits the marimo.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.

dimitsqx avatar Nov 14 '25 18:11 dimitsqx

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?

mscolnick avatar Nov 14 '25 18:11 mscolnick

I think that .marimo.toml takes priority over pyproject, so adding the section to pyproject does not resolve the issue.

Testing the following flow:

  1. Added the section to pyproject.toml
[tool.marimo.runtime]
dotenv = [".env"]
  1. Edited the setting in the UI -> now .marimo.toml does not have the runtime.dotenv setting
  2. Refresh the page

The dotenv location disappeared from the Add Secret window. My guess - the setting from .marimo.toml takes precedence over pyproject.toml

Image

dimitsqx avatar Nov 14 '25 18:11 dimitsqx

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.

dimitsqx avatar Nov 14 '25 18:11 dimitsqx