stablyai/orca · error · EmulatorError
emulator_error
emulator_error
Error message
pm ${op} requires a permission name What it means
Thrown by permissionArgs when op is 'grant' or 'revoke' but the permission argument is undefined, null, or empty/whitespace. The builder cannot construct a valid `adb shell pm grant <pkg> <perm>` line without a permission target. The 'reset' op is exempt because `pm reset-permissions` takes no permission argument.
Source
Thrown at src/main/emulator/android/android-permissions.ts:25
// grant/revoke: `adb -s <serial> shell pm <op> <package> <permission>`
// reset: `adb -s <serial> shell pm reset-permissions <package>`
// `reset` clears every runtime grant, so the permission argument is ignored.
export function permissionArgs(
serial: string,
op: AndroidPermissionOp,
packageName: string,
permission?: string
): string[] {
const base = ['-s', serial, 'shell', 'pm']
// `pm reset-permissions` resets every app's runtime grants and rejects a
// package argument, so it is omitted here.
if (op === 'reset') {
return [...base, 'reset-permissions']
}
// grant/revoke target a single permission, so it must be present.
if (!permission || permission.trim() === '') {
throw new EmulatorError('emulator_error', `pm ${op} requires a permission name`)
}
return [...base, op, packageName, permission]
}
View on GitHub (pinned to 1136503c6a)
Solutions
- Validate the permission name is a non-empty Android permission constant (e.g. android.permission.CAMERA) before calling permissionArgs.
- Filter empty entries out of permission lists before iterating.
- Skip grant/revoke entirely when no permission applies; use op 'reset' only when a full reset is intended.
Example fix
// before: empty permission from config slips through
for (const p of manifest.permissions) {
await run(permissionArgs(serial, 'grant', pkg, p))
}
// after: guard non-empty canonical names
for (const p of manifest.permissions) {
if (!p?.startsWith('android.permission.')) continue
await run(permissionArgs(serial, 'grant', pkg, p))
} Defensive patterns
Strategy: validation
Validate before calling
// Guard the permission argument before building args.
function isValidPermission(p?: string): boolean {
return !!p && p.trim() !== '' && p.startsWith('android.permission.')
} Type guard
function isPermissionName(p?: string): p is string {
return !!p && p.trim() !== ''
} Prevention
- Filter empty strings out of permission lists before iterating.
- Validate permission names start with 'android.permission.' for standard perms.
- Use op 'reset' only when no single permission is targeted.
When it happens
Trigger: permissionArgs(serial, 'grant', pkg) or permissionArgs(serial, 'revoke', pkg) invoked with the fourth argument omitted or set to ''/whitespace. Typically a caller reading the permission name from a config or list that yielded an empty value.
Common situations: A permission grant loop iterating over a list that contains an empty entry; a config field left blank; reading the permission name from a JSON manifest that did not include the expected key; a guard missing before forwarding user input.
Related errors
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/a5b16cb1a46cbb41.
Report an issue: GitHub.