-
Notifications
You must be signed in to change notification settings - Fork 525
Description
Operating System
Linux (WSL2)
Run Mode
Docker
App Version
0.13.0 (branch v0.14.0rc)
Bug Description
API keys entered in the Settings UI are saved only to browser localStorage via Zustand store, but never persisted to the server's credentials.json. This causes authentication failures when agents run because the server reads credentials from credentials.json, not localStorage.
Additionally, the Docker nginx configuration is missing an /api proxy rule, causing all API requests to return the SPA HTML instead of being proxied to the backend server.
Root Cause Analysis
Issue 1: Write path mismatch
In apps/ui/src/components/views/settings-view/api-keys/hooks/use-api-key-management.ts, the handleSave() function only updates the Zustand store:
const handleSave = async () => {
const keys = { anthropic: anthropicKey, google: googleKey, openai: openaiKey };
setApiKeys(keys); // Only saves to Zustand/localStorage
// Missing: api.settings.updateCredentials({ apiKeys: keys })
};Issue 2: Read path mismatch
The hook initializes from useAppStore().apiKeys which is empty after page reload because apiKeys is intentionally excluded from localStorage persistence for security. The hook never fetches credentials from the server on mount.
Issue 3: Docker nginx missing API proxy
In apps/ui/nginx.conf:
location / {
try_files $uri $uri/ /index.html; # All requests fall through to SPA
}
# Missing: location /api/ { proxy_pass http://server:3008; }Issue 4: Setup wizard also affected
apps/server/src/routes/setup/routes/store-api-key.ts writes to .env and process.env but not to credentials.json.
Steps to Reproduce
- Start automaker in Docker mode (
docker compose up) - Open http://localhost:3007
- Go to Settings > API Keys
- Enter an Anthropic API key and click Save
- Run
docker exec automaker-server cat /data/credentials.json- file is empty or missing apiKeys - Try to run an agent - fails with "Claude Code process exited with code 1"
- Refresh the settings page - API key field is empty
Expected Behavior
- API keys saved in Settings UI should persist to
credentials.jsonon the server - On page reload, saved keys should be fetched from the server (masked for security)
- Agent execution should use credentials from
credentials.json - Docker nginx should proxy
/api/*requests to the backend
Actual Behavior
- Keys only saved to browser localStorage
- Keys lost on page reload (localStorage cleared or different browser)
- Agent authentication fails because server has no credentials
- In Docker mode, API requests return HTML instead of proxying to backend
Suggested Fix
use-api-key-management.ts: Callapi.settings.updateCredentials()inhandleSave()use-api-key-management.ts: Fetch masked credentials from server on mount viaapi.settings.getCredentials()store-api-key.ts: AcceptSettingsServiceand write tocredentials.jsonapps/server/src/routes/setup/index.ts: PasssettingsServicetocreateStoreApiKeyHandler()nginx.conf: Add/apilocation block with proxy_pass to server:3008
Related Issues
- [Bug]: App crashes | Claude API Key Disappears #520 - Similar symptom (API key disappears) but different cause (crash-related vs. never persisted)
Screenshots
N/A
Relevant Logs
ERROR [ClaudeProvider] executeQuery() error during execution: {
type: 'execution',
message: 'Claude Code process exited with code 1',
...
}
Browser console when fetching credentials through nginx without proxy:
fetch('/api/settings/credentials', {method: 'GET', credentials: 'include'})
Uncaught (in promise) SyntaxError: Unexpected token '<', "<!doctype "... is not valid JSON
Additional Context
The security notice in the UI incorrectly states "API keys are stored in your browser's local storage" - the intended design appears to be server-side storage in credentials.json, but the write path was never implemented.
Checklist
- I have searched existing issues to ensure this bug hasn't been reported already
- I have provided all required information above