---
name: "Web UI permissions handling unreliable"
---

# Bug 180: Web UI permissions handling unreliable

## Description

Permissions handling in the web UI chat is intermittently unreliable. This is a tracking bug to collect specific problems as they're encountered.

Known issues:

1. **Permission hook returns invalid responses**: The permission hook intermittently returns a malformed response that doesn't match the expected `{"behavior": "allow"}` or `{"behavior": "deny", "message": "..."}` schema. This affects ALL tool types — not just Bash. We've observed it on Edit tool calls (which don't even require explicit permission) as well as Bash calls. The error is:

```json
{
  "code": "invalid_union",
  "errors": [
    [{ "code": "invalid_value", "values": ["allow"], "path": ["behavior"], "message": "Invalid input: expected \"allow\"" }],
    [{ "code": "invalid_value", "values": ["deny"], "path": ["behavior"], "message": "Invalid input: expected \"deny\"" },
     { "expected": "string", "code": "invalid_type", "path": ["message"], "message": "Invalid input: expected string, received undefined" }]
  ]
}
```

This is intermittent — retrying the same tool call often succeeds. Cause unknown.

## How to reproduce

Use the web UI chat with claude-code provider. Perform normal operations (Edit files, run git commands). Intermittently, tool calls fail with the `invalid_union` error above. The same call succeeds on retry.

## How to reproduce

Use the web UI chat with claude-code provider. Perform normal operations (Edit files, run git commands). Intermittently, tool calls fail with the `invalid_union` error above. The same call succeeds on retry. The problem is worse in parallel batches because the cascade bug kills all sibling calls.

## How to reproduce

### Issue 1 (intermittent hook failure)
Use the web UI chat with claude-code provider. Perform normal operations (Edit files, run git commands). Intermittently, tool calls fail with the `invalid_union` error above. The same call succeeds on retry.

### Issue 3 (chained commands)
Run a Bash call with chained commands like:
```
git status && echo "---" && git log --oneline
```
This fails permission validation even though `Bash(git *)` is in the allow list.

## How to reproduce

Ask the agent to check git status across all worktrees. If it chains commands like:

```
git -C .story_kit/worktrees/163_story_foo status --porcelain 2>&1 | head -5 && echo "---COMMITS---" && git -C .story_kit/worktrees/163_story_foo log --oneline master..HEAD 2>&1 | head -3
```

This fails with:

```json
{
  "code": "invalid_union",
  "errors": [
    [{ "code": "invalid_value", "values": ["allow"], "path": ["behavior"], "message": "Invalid input: expected \"allow\"" }],
    [{ "code": "invalid_value", "values": ["deny"], "path": ["behavior"], "message": "Invalid input: expected \"deny\"" },
     { "expected": "string", "code": "invalid_type", "path": ["message"], "message": "Invalid input: expected string, received undefined" }]
  ]
}
```

But individual `git -C ... status --porcelain` calls (even 11+ in parallel) work fine.

## How to reproduce

Ask the agent to check git status across all worktrees. It will attempt to run 11+ parallel Bash calls like:

```
git -C .story_kit/worktrees/163_story_foo status --porcelain
git -C .story_kit/worktrees/165_bug_bar status --porcelain
git -C .story_kit/worktrees/166_story_baz status --porcelain
... (11 total)
```

Each command individually works fine and matches the `Bash(git *)` permission rule. But when all 11 are fired in a single parallel batch, they all fail with:

```json
{
  "code": "invalid_union",
  "errors": [
    [{ "code": "invalid_value", "values": ["allow"], "path": ["behavior"], "message": "Invalid input: expected \"allow\"" }],
    [{ "code": "invalid_value", "values": ["deny"], "path": ["behavior"], "message": "Invalid input: expected \"deny\"" },
     { "expected": "string", "code": "invalid_type", "path": ["message"], "message": "Invalid input: expected string, received undefined" }]
  ]
}
```

The first call gets this error, and all remaining calls fail with `"Sibling tool call errored"`.

Running the same commands in batches of 3 works fine.

## How to reproduce

Ask the agent to check git status across all worktrees. It will attempt to run 11+ parallel Bash calls like:

```
git -C .story_kit/worktrees/163_story_foo status --porcelain
git -C .story_kit/worktrees/165_bug_bar status --porcelain
git -C .story_kit/worktrees/166_story_baz status --porcelain
... (11 total)
```

Each command individually works fine and matches the `Bash(git *)` permission rule. But when all 11 are fired in a single parallel batch, they all fail with:

```json
{
  "code": "invalid_union",
  "errors": [
    [{ "code": "invalid_value", "values": ["allow"], "path": ["behavior"], "message": "Invalid input: expected \"allow\"" }],
    [{ "code": "invalid_value", "values": ["deny"], "path": ["behavior"], "message": "Invalid input: expected \"deny\"" },
     { "expected": "string", "code": "invalid_type", "path": ["message"], "message": "Invalid input: expected string, received undefined" }]
  ]
}
```

The first call gets this error, and all remaining calls fail with `"Sibling tool call errored"`.

Running the same commands in batches of 3 works fine.

## How to Reproduce

Issue 1: Start a chat session using claude-code provider, trigger a tool call that requires permission (e.g. a Bash command not in the allow list). Observe that the permission dialog sometimes fails to appear.

Issue 2: Have the agent run 10+ parallel Bash tool calls. Observe that the batch fails with hook validation errors even though individual calls succeed.

## Actual Result

Issue 1: Agent hangs waiting for permission response that the user has no way to grant.
Issue 2: All parallel calls fail with "Sibling tool call errored" cascade.

## Expected Result

Issue 1: Permission dialog should reliably appear whenever the agent requests tool approval.
Issue 2: Parallel tool calls should either all be validated independently, or failures should be isolated rather than cascading.

## Acceptance Criteria

- [ ] Permission request dialog reliably appears in the web UI when the agent needs tool approval
- [ ] Parallel Bash tool calls do not cascade-fail due to hook/permission validation errors
- [ ] Root cause identified for each sub-issue (web UI, Claude Code SDK, or hook system)
