fix: treat llm_base_url="" as explicit clear in store_llm_settings#13471
Merged
enyst merged 2 commits intoOpenHands:mainfrom Mar 20, 2026
Merged
fix: treat llm_base_url="" as explicit clear in store_llm_settings#13471enyst merged 2 commits intoOpenHands:mainfrom
enyst merged 2 commits intoOpenHands:mainfrom
Conversation
Previously, `if not settings.llm_base_url:` caught both `None` (field not provided) and `""` (explicitly cleared by the user). When a user deleted the Base URL in Advanced view, or saved from Basic view (which sends `llm_base_url: ""`), the backend would overwrite their intent by running auto-detection via `get_provider_api_base()` or preserving the old URL — making it impossible to clear a previously-set base URL. Fix: split the condition into two explicit branches: - `llm_base_url is None` → not provided at all; preserve existing or auto-detect as before (no behavior change for partial saves/MCP saves) - `llm_base_url == ""` → explicit clear; normalize to None without running auto-detection Adds a regression test `test_store_llm_settings_advanced_view_clear_removes_base_url` and updates `test_store_llm_settings_partial_update` to assert the now- correct behavior (None instead of auto-detected URL). Fixes OpenHands#13420 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes lint CI failure by converting double quotes to single quotes per the project's ruff.toml config (inline-quotes = "single"). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Collaborator
|
Hey @LarytheLord thank you for the contribution! Could you maybe show a video that it works, or logs (though video would be nice I think), and that is still works for the previous issue? |
Contributor
Author
|
Thanks @enyst — here's the test evidence: Regression test ( Existing behavior preserved (
All 3 tests pass: Full suite (16/16): I can record a UI walkthrough too if you'd like, but the logic is fully covered by these tests. The key distinction is the |
This was referenced Mar 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #13420 — it is currently impossible to persist an empty
llm_base_urlfrom the settings UI.Root cause:
store_llm_settingsusedif not settings.llm_base_url:which catches bothNone(field not provided at all) and""(explicitly cleared by the user). When the user:llm_base_url: ""to clear advanced settings), orthe backend treated
""the same as "not provided", triggering auto-detection viaget_provider_api_base()and overwriting the user's intent. The old base URL kept coming back.Fix: Split the condition into two explicit branches:
The
Nonepath has identical behavior to before. Only""changes: instead of triggering auto-detection, it now normalizes toNoneand returns.Test plan
test_store_llm_settings_partial_updateto assertNone(the correct post-fix behavior) instead of the auto-detected URLtest_store_llm_settings_advanced_view_clear_removes_base_urlas a named regression test for this issuetest_settings_store_functions.pypasstest_store_llm_settings_mcp_update_preserves_base_url) continues to pass — theNonepath (field not sent) is unchanged🤖 Generated with Claude Code