Skip to content

fix: treat empty llm api_key as no change when saving settings - #17809

Draft
all-hands-bot wants to merge 1 commit into
mainfrom
openhands/fix-empty-api-key-wipe
Draft

all-hands-bot wants to merge 1 commit into
mainfrom
openhands/fix-empty-api-key-wipe

Conversation

@all-hands-bot

@all-hands-bot all-hands-bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

HUMAN:


AGENT:

Why

When a user changes only the LLM model/provider via the settings UI without re-typing the API key, the saved LLM profile is persisted with an empty api_key. Switching to that profile mid-conversation then fails with an LLMAuthenticationError ("You must provide an API key"), because the old key was overwritten with "" on save. The root cause:the API-key input only shows a <hidden> placeholder, so an untouched key field submits as an empty string. saveSettingsMutationFn in src/hooks/mutation/use-save-settings.ts trimmed and forwarded that "" verbatim;the backend deep_merge treats only None as "preserve", so "" overwrites the stored key.

Summary

  • In use-save-settings.ts, an empty( all-whitespace) llm.api_key is now dropped from the save diff instead of forwarded as "", so "no change" no longer wipes the stored key。

  • If the key was the only changed field in the llm diff, the empty llm object is also dropped so the backend never sees a llm: {} no-op patch。

  • A real (non-empty) key is still trimmed and forwarded as before。

Issue Number

Fixes #17806

How to Test

  1. npm ci
  2. npx vitest run __tests__/hooks/mutation/use-save-settings.test.ts — all 7 tests pass, including 3 new ones covering:d dropping an empty api_key from the payload,d dropping the whole llm diff when the key was the only field,and keeping a non-empty key( trimmed。
  3. npx vitest run __tests__/api/settings-service.test.ts plus __tests__/routes/llm-settings.test.tsx — 39 tests pass( no regressions in the settings save flow.

Video/Screenshots

The change is a pure outgoing request-payload transform. The three new unit tests in __tests__/hooks/mutation/use-save-settings.test.ts exercise the behavior end-to-end for this data path:a spy on SettingsService.saveSettings asserts the exact forwarded payload when the API key is empty, whitespace-only, or real.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

The complementary backend hardening( treating api_key == "" as "no change" in deep_merge/Settings.update) was intentionally scoped out per the issue — this fixes the frontend source of the bad payload. The behavior is consistent with the empty-base_url special-casing already present in resolve_llm_base_url.

AGENT Note: This PR description was created by an AI agent (OpenHands)on behalf of the repository contributor.

@all-hands-bot can click here to continue refining the PR


🐳 Docker images for this PR

• GHCR package: https://github.com/OpenHands/OpenHands/pkgs/container/agent-canvas

Component Value
Image ghcr.io/openhands/agent-canvas
Architectures amd64, arm64
Agent Server ghcr.io/openhands/agent-server:1.49.6-python
Automation openhands-automation==1.15.1
Commit 1e94f71466e5f44be579d9324f032d24039c6f97

Pull (multi-arch manifest)

# Multi-arch manifest — Docker automatically pulls the correct architecture
docker pull ghcr.io/openhands/agent-canvas:sha-1e94f71

Run

docker run -it --rm \
  -p 8000:8000 \
  ghcr.io/openhands/agent-canvas:sha-1e94f71

All tags pushed for this build

ghcr.io/openhands/agent-canvas:sha-1e94f71-amd64
ghcr.io/openhands/agent-canvas:openhands-fix-empty-api-key-wipe-amd64
ghcr.io/openhands/agent-canvas:pr-17809-amd64
ghcr.io/openhands/agent-canvas:sha-1e94f71-arm64
ghcr.io/openhands/agent-canvas:openhands-fix-empty-api-key-wipe-arm64
ghcr.io/openhands/agent-canvas:pr-17809-arm64
ghcr.io/openhands/agent-canvas:sha-1e94f71
ghcr.io/openhands/agent-canvas:openhands-fix-empty-api-key-wipe
ghcr.io/openhands/agent-canvas:pr-17809

About Multi-Architecture Support

  • Each tag (e.g., sha-1e94f71) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., sha-1e94f71-amd64) are also available if needed

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix A bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Changing LLM model without re-typing the API key wipes the stored key (auth errors on profile switch)

2 participants