# Plan Mode Bug Fix - Claude WebUI

**Datum:** 2025-12-16
**Status:** DEPLOYED

## Das Problem

Beim Plan Mode Approval im WebUI kam ein API Error:
```
API Error: 400 {"type":"error","error":{"type":"invalid_request_error",
"message":"messages.98.content.0: unexpected tool_use_id found in tool_result blocks:
toolu_01R6yjX7gqduKgMAuYuPzMeG. Each tool_result block must have a corresponding
tool_use block in the previous message."}}
```

### Ursache
- Wenn das WebUI ein Plan Approval sendet, muss die `tool_use_id` mit einem vorherigen `tool_use` Block matchen
- Bei **Message History Compaction** gehen die ursprünglichen `tool_use` Blöcke verloren
- Das WebUI sendete `tool_result` für Permissions, aber die zugehörigen `tool_use` IDs existierten nicht mehr

## Die Lösung

### 1. Scope-Problem gefixt
`setPermissionModeViaControl` wurde aus `startClaudeSession` in den äußeren WebSocket-Scope verschoben:

**Datei:** `backend/server.js` (Zeile ~307)
```javascript
// Helper to set permission mode via control protocol (needs claudeProcess)
const setPermissionModeViaControl = (mode) => {
  if (!claudeProcess) return;
  const modeRequestId = generateRequestId();
  const modeRequest = {
    type: 'control_request',
    request_id: modeRequestId,
    request: {
      subtype: 'set_permission_mode',
      mode: mode
    }
  };
  console.log(`[${sessionId}] Auto-switching permission mode to: ${mode}`);
  claudeProcess.stdin.write(JSON.stringify(modeRequest) + '\n');
  pendingControlRequests.set(modeRequestId, { type: 'set_permission_mode', mode });
};
```

### 2. Permission Responses als `control_response` statt `tool_result`

**Datei:** `backend/server.js` (Zeile ~641)
```javascript
// All permission responses (including ExitPlanMode/plan approval) use control_response
// This avoids tool_result issues when message history is compacted
const permResponse = {
  type: 'control_response',
  response: {
    subtype: 'success',
    request_id: data.requestId,
    response: data.allow
      ? { behavior: 'allow', updated_input: data.updatedInput || null }
      : { behavior: 'deny', message: data.message || 'User denied permission' }
  }
};
```

### 3. Plan Mode State Tracking

**Datei:** `backend/server.js` (Zeile ~302)
```javascript
let inPlanMode = false;  // Track if we're in plan mode
```

Bei `ExitPlanMode` Permission Request (Zeile ~441):
```javascript
// Track plan mode state for ExitPlanMode
if (isPlanApproval && !inPlanMode) {
  savedPermissionMode = currentPermissionMode;
  inPlanMode = true;
  console.log(`[${sessionId}] Entering plan mode, saved mode: ${savedPermissionMode}`);
}
```

## Deployment

Nach Code-Änderungen muss das Backend-Image neu gebaut werden:

```bash
cd /home/sumdex/projects/claude-web-ui
docker compose build backend
docker compose up -d backend
```

**Wichtig:** Der Backend-Code ist NICHT als Volume gemountet, sondern im Image gebaut!

### Verifizieren dass der Fix deployed ist:
```bash
docker exec claude-webui-backend cat /app/server.js | grep "setPermissionModeViaControl"
```

## Relevante Dateien

| Datei | Beschreibung |
|-------|--------------|
| `backend/server.js` | Haupt-Backend, WebSocket Handler, Permission Handling |
| `frontend/src/hooks/useClaudeSession.js` | Frontend Hook für Claude Session |
| `frontend/src/components/PermissionDialog.jsx` | Permission UI Dialog |
| `docker-compose.yml` | Container Konfiguration |

## Session-Dump

Falls weitere Analyse nötig:
```
/home/sumdex/projects/webui-workspace/session-dump-20251216-164148.jsonl
```

## Technischer Hintergrund

### Control Protocol vs Tool Results
- **tool_result:** Muss immer mit einem `tool_use` in der vorherigen Nachricht matchen
- **control_response:** Hat diese Einschränkung nicht, funktioniert unabhängig von Message History

### Message Compaction
Claude Code kompaktiert die Message History um Context zu sparen. Dabei können `tool_use` Blöcke entfernt werden, was zu ID-Mismatches führt wenn später `tool_result` mit diesen IDs gesendet wird.

## Test

1. WebUI öffnen: http://100.105.142.13:3000
2. Neue Session starten
3. Eine Anfrage stellen die Plan Mode triggert (z.B. "Implementiere Feature X")
4. Plan Mode Approval im UI bestätigen
5. Es sollte KEIN `unexpected tool_use_id` Error mehr kommen
