eval is the most powerful automation verb, so it is double locked. The session must be started with extension dev --allow-eval, and the CLI must present the session token that the dev server wrote for this project and browser. Both happen automatically when you run the two commands from the same project root.
When to use eval
- You want to poke at extension state (
chrome.runtime, storage, DOM) without opening DevTools. - An agent needs to run a check inside the page and get a structured value back.
- You want a scriptable REPL against the background worker or a live tab.
Usage
Arguments and flags
Extension pages (
popup, options, sidebar, devtools, newtab, history, bookmarks) answer through their own in-page relay, so the surface must be open in the browser. Use open (documented in Trigger actions and commands) to open one first.
Pretty output prints the value itself: strings as-is, everything else as indented JSON. The envelope shape appears only under --output json (see Result envelope).
How the unlock works
extension dev --allow-evalstarts the session with eval enabled.--allow-evalalso unlocks the other control verbs, so you do not need both flags.- The dev server writes a random session token to
.extension-js/control-token-<browser>with0600permissions. The token is keyed per browser, so concurrent sessions do not collide. evalreads that token from the project root and presents it during the handshake.
--allow-eval refuses the call, and the refusal names --allow-eval as the flag to add. A missing token fails with E_TOKEN_MISSING, a mismatched or disabled one with E_EVAL_REFUSED.
Failure modes
- The expression threw inside the target:
E_EVAL, with a hint that the expression itself is at fault. This is a result, not a transport error. - No session for the browser:
E_SESSION_NOT_FOUND, with the exactextension devcommand to run. - Target surface not open, or a stale
--tabid:E_TARGET_NOT_FOUND. Useinspect --list-tabsto find live ids. - The call outlived
--timeout:E_TIMEOUT.
0 when the expression succeeds and 1 otherwise, so scripts can gate on it directly. Run doctor when every verb fails and you want the broken leg named.
Next steps
- Find tab ids and DOM state to target with
inspect. - Read or write
chrome.storagewithout writing an expression withstorage. - Read the wider debugging workflow in Debugging.
- Review the machine output format in Result envelope.

