moeru-ai/airi · error · Error
Cannot grant permissions to unknown plugin "${extensionId}".
Error message
Cannot grant permissions to unknown plugin "${extensionId}". What it means
Thrown by `PermissionRegistry.grant()` when no permission snapshot exists for the given `extensionId`. Granting is an incremental operation that intersects a new grant with an existing snapshot's requested ceiling, so the extension must already have been initialized via `initialize()`. The store miss is checked before any grant merging or intersection logic runs.
Source
Thrown at packages/plugin-sdk/src/plugin-host/runtimes/shared/services/permissions.ts:339
if (!existing) {
throw new Error(`Cannot declare permissions for unknown plugin "${extensionId}".`)
}
const requested = normalizeDeclaration(requestedDeclaration)
const snapshot: PermissionSnapshot = {
requested: mergePermissionDeclarations(existing.requested, requested),
granted: existing.granted,
revision: existing.revision + 1,
}
this.store.set(extensionId, snapshot)
return snapshot
}
grant(extensionId: string, grant: ModulePermissionGrant) {
const existing = this.store.get(extensionId)
if (!existing) {
throw new Error(`Cannot grant permissions to unknown plugin "${extensionId}".`)
}
const mergedGranted = mergePermissions(existing.granted, grant)
const snapshot: PermissionSnapshot = {
requested: existing.requested,
granted: intersectPermissions(existing.requested, mergedGranted),
revision: existing.revision + 1,
}
this.store.set(extensionId, snapshot)
return snapshot
}
get(extensionId: string) {
return this.store.get(extensionId)
}
isAllowed(extensionId: string, area: ModulePermissionArea, action: string, key: string) {
const snapshot = this.store.get(extensionId)View on GitHub (pinned to 27111382b4)
Solutions
- Ensure `permissions.initialize(extensionId, requestedDeclaration)` runs before any `grant()` for the same extension id.
- Check `permissions.get(extensionId)` before granting, and initialize if absent (the grant will then be intersected with the requested ceiling).
- Confirm the extension id string matches exactly what was used at registration.
- On store reset/reload, replay the initialize step before granting.
Example fix
// before
permissions.grant(extensionId, grant)
// after
if (!permissions.get(extensionId)) {
permissions.initialize(extensionId, requestedCeiling)
}
permissions.grant(extensionId, grant) Defensive patterns
Strategy: validation
Validate before calling
if (!permissions.get(extensionId)) {
permissions.initialize(extensionId, requestedCeiling)
}
permissions.grant(extensionId, grant) Type guard
function isPermissionInitialized(extensionId: string): boolean {
return permissions.get(extensionId) !== undefined
} Try / catch
try {
permissions.grant(extensionId, grant)
} catch (e) {
if (e instanceof Error && e.message.includes('Cannot grant permissions to unknown plugin')) {
permissions.initialize(extensionId, requestedCeiling)
permissions.grant(extensionId, grant)
return
}
throw e
} Prevention
- Initialize each extension's permission snapshot before granting in response to user prompts.
- Use identical extension id strings across initialize, declare, and grant call sites.
- Guard grant calls with permissions.get(extensionId) in async flows (e.g. prompt callbacks).
- After reload/test store resets, re-run initialize before granting.
When it happens
Trigger: Calling `permissions.grant(extensionId, grant)` before `permissions.initialize(extensionId, ...)` has created a snapshot for that extension. Also caused by a typo or scope mismatch in the extension id, or by granting after the store was cleared (reload/test) without re-initializing.
Common situations: Permission-prompt flow that grants in response to a user action before the extension's permission record was seeded; host code that reuses a stale extension id after a plugin reload into a fresh store; tests that call grant directly.
Related errors
- Cannot declare permissions for unknown plugin "${extensionId
- Permission denied: ${details.area}.${details.action} "${deta
- Module `${moduleId}` was not found.
- Godot stage is not running.
- Godot stage bridge is not connected.
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/c35c06f2e4c6c62d.
Report an issue: GitHub.