stablyai/orca · error · RuntimeClientError
invalid_argument
invalid_argument
Error message
<op> must be grant, revoke, or reset
What it means
Thrown by parseEmulatorPermissionRequest when the required --op flag is set to anything other than 'grant', 'revoke', or 'reset'. The op is the discriminator for the whole request: grant/revoke need a permission (and optionally a package), reset takes neither. An unrecognized op cannot be mapped to an Android pm action, so it is rejected before any further parsing.
Source
Thrown at src/cli/emulator-permissions-args.ts:15
import { getOptionalStringFlag, getRequiredStringFlag } from './flags'
import { RuntimeClientError } from './runtime-client'
export type EmulatorPermissionRequest = {
op: 'grant' | 'revoke' | 'reset'
packageName?: string
permission?: string
}
export function parseEmulatorPermissionRequest(
flags: Map<string, string | boolean>
): EmulatorPermissionRequest {
const op = getRequiredStringFlag(flags, 'op')
if (op !== 'grant' && op !== 'revoke' && op !== 'reset') {
throw new RuntimeClientError('invalid_argument', '<op> must be grant, revoke, or reset')
}
const packageName = getOptionalStringFlag(flags, 'package')
const permission = getOptionalStringFlag(flags, 'permission')
if (op === 'reset') {
if (packageName || permission) {
throw new RuntimeClientError(
'invalid_argument',
'reset does not accept package or permission'
)
}
return { op }
}
if (!permission) {
throw new RuntimeClientError('invalid_argument', `<permission> is required for ${op}`)
}
return { op, packageName: packageName ?? getRequiredStringFlag(flags, 'package'), permission }
}
View on GitHub (pinned to 1136503c6a)
Solutions
- Pass --op as exactly 'grant', 'revoke', or 'reset'.
- If you meant to wipe all permissions for a package, use --op reset (without --package/--permission).
- Check the calling script against the EmulatorPermissionRequest type definition.
Example fix
// before new Map([['op','allow'],['permission','CAMERA']]) // after new Map([['op','grant'],['permission','CAMERA']])
Defensive patterns
Strategy: type-guard
Validate before calling
const VALID_OPS = new Set(['grant', 'revoke', 'reset'])
function pickOp(flags: Map<string, string | boolean>): 'grant' | 'revoke' | 'reset' {
const op = flags.get('op')
if (typeof op !== 'string' || !VALID_OPS.has(op)) {
throw new Error(`--op must be one of ${[...VALID_OPS].join('|')}`)
}
return op as 'grant' | 'revoke' | 'reset'
} Type guard
function isEmulatorPermissionOp(v: unknown): v is 'grant' | 'revoke' | 'reset' {
return v === 'grant' || v === 'revoke' || v === 'reset'
} Try / catch
try {
parseEmulatorPermissionRequest(flags)
} catch (e) {
if (e instanceof RuntimeClientError && e.code === 'invalid_argument') {
// prompt user for a valid --op
}
throw e
} Prevention
- Constrain --op to a literal union at the CLI surface.
- In scripts, derive op from an enum rather than a free string.
When it happens
Trigger: Calling parseEmulatorPermissionRequest with a flags map whose 'op' entry is a string outside the set {grant, revoke, reset}, e.g. `new Map([['op','allow']])` or omitting a value so the parser coerces it incorrectly.
Common situations: Typo in an emulator-permission CLI command (`orca emulator permissions --op grannt`), a script passing a stale op name from an older API, or confusion with the host's own permission verb set.
Related errors
- bin.orca target is not executable: ${binTarget}
- invalid_argument
- invalid_argument
- invalid_argument
- invalid_argument
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/d168c1e9137e9ad1.
Report an issue: GitHub.