Plugin SDK: permission.ask hook is never called #6687

Closed
opened 2026-02-16 18:04:57 -05:00 by yindo · 1 comment
Owner

Originally created by @schickling on GitHub (Jan 18, 2026).

Originally assigned to: @thdxr on GitHub.

Summary

The permission.ask hook defined in the @opencode-ai/plugin SDK is never triggered because OpenCode's permission system uses PermissionNext.ask() which emits Bus events instead of calling Plugin.trigger("permission.ask", ...).

Expected Behavior

When a permission check requires user approval, plugins should receive the permission.ask hook callback as documented in the SDK.

Actual Behavior

The permission.ask hook is never called. Instead, permission.asked events are emitted via the Bus system and can only be captured through the generic event hook.

Root Cause Analysis

OpenCode has two permission modules:

  1. permission/index.ts (legacy/unused) - Contains Permission.ask() that calls Plugin.trigger("permission.ask", ...) at line 134
  2. permission/next.ts (actively used) - Contains PermissionNext.ask() that publishes Bus.publish(Event.Asked, info) at line 140

All actual permission checks use PermissionNext.ask(), which:

  • Emits permission.asked via the Bus system (triggers generic event hook)
  • Does NOT call Plugin.trigger("permission.ask", ...)

Code Evidence

// packages/opencode/src/permission/next.ts:128-141 (ACTIVELY USED)
if (rule.action === "ask") {
  const id = input.id ?? Identifier.ascending("permission")
  return new Promise<void>((resolve, reject) => {
    const info: Request = {
      id,
      ...request,
    }
    s.pending[id] = {
      info,
      resolve,
      reject,
    }
    Bus.publish(Event.Asked, info)  // <-- Emits "permission.asked", NOT "permission.ask" hook
  })
}

Suggested Fix

Either:

  1. Add Plugin.trigger("permission.ask", info) call in PermissionNext.ask() before/after the Bus publish
  2. Or document that plugins should use the event hook with type: "permission.asked" instead

Workaround

Plugins can listen to permission events via the generic event hook:

export default {
  name: "my-plugin",
  hooks: {
    event: async (event) => {
      if (event.type === "permission.asked") {
        // Handle permission request
        console.log("Permission requested:", event.properties)
      }
    }
  }
}

Environment

  • OpenCode version: latest (dev branch)
  • Discovered while building an external agent manager that tracks session state
Originally created by @schickling on GitHub (Jan 18, 2026). Originally assigned to: @thdxr on GitHub. ## Summary The `permission.ask` hook defined in the `@opencode-ai/plugin` SDK is never triggered because OpenCode's permission system uses `PermissionNext.ask()` which emits Bus events instead of calling `Plugin.trigger("permission.ask", ...)`. ## Expected Behavior When a permission check requires user approval, plugins should receive the `permission.ask` hook callback as documented in the SDK. ## Actual Behavior The `permission.ask` hook is never called. Instead, `permission.asked` events are emitted via the Bus system and can only be captured through the generic `event` hook. ## Root Cause Analysis OpenCode has **two** permission modules: 1. **`permission/index.ts`** (legacy/unused) - Contains `Permission.ask()` that calls `Plugin.trigger("permission.ask", ...)` at line 134 2. **`permission/next.ts`** (actively used) - Contains `PermissionNext.ask()` that publishes `Bus.publish(Event.Asked, info)` at line 140 All actual permission checks use `PermissionNext.ask()`, which: - Emits `permission.asked` via the Bus system (triggers generic `event` hook) - Does **NOT** call `Plugin.trigger("permission.ask", ...)` ### Code Evidence ```typescript // packages/opencode/src/permission/next.ts:128-141 (ACTIVELY USED) if (rule.action === "ask") { const id = input.id ?? Identifier.ascending("permission") return new Promise<void>((resolve, reject) => { const info: Request = { id, ...request, } s.pending[id] = { info, resolve, reject, } Bus.publish(Event.Asked, info) // <-- Emits "permission.asked", NOT "permission.ask" hook }) } ``` ## Suggested Fix Either: 1. Add `Plugin.trigger("permission.ask", info)` call in `PermissionNext.ask()` before/after the Bus publish 2. Or document that plugins should use the `event` hook with `type: "permission.asked"` instead ## Workaround Plugins can listen to permission events via the generic `event` hook: ```typescript export default { name: "my-plugin", hooks: { event: async (event) => { if (event.type === "permission.asked") { // Handle permission request console.log("Permission requested:", event.properties) } } } } ``` ## Environment - OpenCode version: latest (dev branch) - Discovered while building an external agent manager that tracks session state
yindo closed this issue 2026-02-16 18:04:58 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Jan 18, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #7006: permission.ask plugin hook is defined but not triggered

This appears to be the same issue with identical root cause analysis and suggested fixes. Feel free to ignore if your specific case differs.

@github-actions[bot] commented on GitHub (Jan 18, 2026): This issue might be a duplicate of existing issues. Please check: - #7006: `permission.ask` plugin hook is defined but not triggered This appears to be the same issue with identical root cause analysis and suggested fixes. Feel free to ignore if your specific case differs.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#6687