# 動作 (https://oh-my-webbridge.github.io/zh-mo/reference/actions/)

> **技術預覽**
>
> omw 目前是技術預覽版，正在快速迭代。**之後的版本一定會有破壞相容性的變更。**

{/* Generated from actions.zh-tw.mdx by scripts/i18n.mjs. Edit the zh-TW page instead. */}

每個瀏覽器動作都經由 daemon 的 `POST /command`，位址為 `http://127.0.0.1:17373`。請求帶有 `omw connection` 印出的 Bearer token。CLI 以 `omw call` 包裝它，SDK 以 `call` 包裝它（請見 [CLI](https://oh-my-webbridge.github.io/md/zh-mo/reference/cli/content.md) 與 [SDK](https://oh-my-webbridge.github.io/md/zh-mo/reference/sdk/content.md)）。

## 請求 [#requests]

| 欄位        | 型別   | 意義                                                                                                            |
| ----------- | ------ | --------------------------------------------------------------------------------------------------------------- |
| `session`   | string | 工作階段名稱，由 1 到 96 個字元組成，可用字母（包括 CJK）、數字、`_`、`.` 或 `-`。必填。                        |
| `action`    | string | 下列表格中的動作名稱。必填。                                                                                    |
| `args`      | object | 動作引數。預設為 `{}`。                                                                                         |
| `timeoutMs` | number | 期限，單位為毫秒，範圍 1 到 120000，預設 30000。它涵蓋排隊與執行。其他值（包括 0）會以 `invalid_request` 失敗。 |
| `browser`   | string | `chrome` 或 `firefox`。省略時，依序使用已綁定到該工作階段的瀏覽器、唯一已連線的瀏覽器，或 Chrome。              |

本文是一個 JSON 物件，上限 2 MiB，不可含有未知欄位。名稱與既有綁定重複的工作階段，依 [工作階段與分頁](https://oh-my-webbridge.github.io/md/zh-mo/sessions/content.md) 的規則路由。

```json
{
  "session": "research",
  "action": "navigate",
  "args": { "url": "https://example.com", "group_title": "Research" },
  "timeoutMs": 30000
}
```

請求本文也可以帶 `id`，這是一個字串，回覆會原樣帶回。省略時，daemon 會指派一個以小寫 36 進位表示的 [Snowflake ID](https://en.wikipedia.org/wiki/Snowflake_ID)。成功的呼叫會回傳這個 id 與動作結果：

```json
{
  "id": "uvwoyqsusjk",
  "result": { "success": true, "tabId": 412, "url": "https://example.com/" }
}
```

失敗的呼叫回傳 id 與錯誤，而不是結果，並帶有 [錯誤](#errors) 表格中的 HTTP 狀態碼：

```json
{
  "id": "uvwoyqsusjk",
  "error": { "code": "stale_ref", "message": "element reference expired; take a fresh snapshot" }
}
```

頁面動作在工作階段目前的分頁中執行。傳入 `tabId`（或 `tab`），即可操作該工作階段持有的另一個分頁，而不必切換過去。

## 導覽與分頁 [#navigation-and-tabs]

| 動作            | 引數                                       | 備註                                                                                                         |
| --------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `navigate`      | `url`、`newTab`、`group_title`、預設集欄位 | 除非工作階段已有目前分頁，或設定了 `newTab`，否則開啓一個背景任務分頁。URL 必須是 HTTP(S) 或 `about:blank`。 |
| `find_tab`      | `url`（完整 URL 或主機名稱）、`active`     | 為工作階段認領既有分頁。`active: true` 借用瀏覽器的使用中分頁。回傳 `tabId`、`url`、`borrowed`。             |
| `list_tabs`     | 無                                         | 列出這個工作階段擁有或借用的分頁，含 `tabId`、`url`、`title`、`active`、`borrowed`、`groupTitle`。           |
| `switch_tab`    | `tabId`                                    | 讓該分頁成為目前分頁。已被丟棄的分頁會先重新載入；結果會回報 `revived`。                                     |
| `window_new`    | `url`、預設集欄位                          | 開啓獨立的視窗，認領其分頁，並回傳 `tabId` 與 `windowId`。                                                   |
| `close_tab`     | `tabId`                                    | 關閉工作階段建立的分頁。借用的分頁不會被關閉。                                                               |
| `close_session` | 無                                         | 關閉任務分頁、釋放借用的分頁，並移除瀏覽器綁定。回傳已關閉的分頁數量。                                       |
| `history`       | `cmd`：`list`、`back`、`forward`、`reload` | `list` 回傳導覽項目。每次 `history` 呼叫都會丟棄該分頁的參照與框架選擇。                                     |

一個工作階段最多持有 32 個分頁，任務分頁與借用的分頁合計。

## 讀取 [#reading]

| 動作            | 引數                                                    | 備註                                                                                                                                                  |
| --------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `snapshot`      | `interactive`、`maxDepth`                               | 帶有 `@e` 參照的無障礙樹，另含 `url`、`title`、`truncated`。深度上限為 64。輸出在 4000 個節點或 192000 個字元時停止。                                 |
| `find`          | `query`、快照欄位                                       | 對快照各行做不分大小寫的搜尋。最多 100 筆符合。                                                                                                       |
| `read_page`     | 無                                                      | `url`、`title`，以及 `document.body.innerText` 的前 192000 個字元。                                                                                   |
| `evaluate`      | `code`、`contextId`                                     | 執行一個運算式，並回傳 `{ type: "value", value }`。需要 `await` 時，使用非同步 IIFE。                                                                 |
| `get`           | `selector`、`property`、`attribute`                     | `text`、`html`、`value`、`attr`、`count`、`box`、`styles`、`title`、`url`。                                                                           |
| `is`            | `selector`、`property`                                  | `visible`、`enabled`、`checked`、`editable`。回傳布林值 `value`。                                                                                     |
| `locate`        | `by`、`value`、`name`、`nth`、`cmd`、`text`、`property` | 依 `by`（`role`、`text`、`label`、`placeholder`、`alt`、`title`、`testid`、`css`、`xpath`）建立選擇器，並執行 `cmd`，這是一個元素動作，預設為 `get`。 |
| `dialog_status` | 無                                                      | 以 `dialog` 回傳待處理的 JavaScript 對話框，或回傳 `null`。                                                                                           |

## 輸入 [#input]

| 動作                               | 引數                                                               | 備註                                                                                                                                                                |
| ---------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `click`、`dblclick`、`mouse_click` | `selector`，或 `x` 與 `y`、`button`                                | 在元素中心送出滑鼠事件。                                                                                                                                            |
| `hover`                            | `selector`                                                         | 把指標移到元素上。                                                                                                                                                  |
| `fill`                             | `selector`、`value`                                                | 取代 input、textarea 或 contenteditable 元素的內容。`value` 為空字串時會清空內容。                                                                                  |
| `key_type`                         | `text`、`selector`                                                 | 在已聚焦的元素插入文字，或先聚焦 `selector`。                                                                                                                       |
| `send_keys`                        | `keys`                                                             | 單一按鍵，或 `Control+A`、`Meta+A` 這類組合鍵。具名按鍵包括 `Enter`、`Tab`、`Escape`、`Backspace`、`Delete`、方向鍵、`Home`、`End`、`PageUp`、`PageDown`、`Space`。 |
| `keyboard`                         | `cmd`：`down`、`up`、`insertText`；`key`、`text`                   | 較低階的按鍵控制，用於按住修飾鍵。                                                                                                                                  |
| `mouse`                            | `cmd`：`move`、`down`、`up`、`wheel`；`x`、`y`、`button`、`amount` | 原始的指標控制。                                                                                                                                                    |
| `scroll`                           | `selector`，或 `direction`、`amount`、`x`、`y`                     | 指定選擇器時，把該元素捲動到中間。否則依 `amount`（0 到 100000，預設 600）朝 `up`、`down`、`left` 或 `right` 滾動滾輪。                                             |
| `select_option`                    | `selector`、`value`                                                | 以值或顯示文字比對選項，然後觸發 `input` 與 `change`。                                                                                                              |
| `drag`                             | `from`、`to`                                                       | 在 `from` 按下，分十個步驟移動，並在 `to` 放開。                                                                                                                    |
| `focus`、`check`、`uncheck`        | `selector`                                                         | `check` 與 `uncheck` 會先讀取目前狀態，並驗證結果；重複執行不會切換狀態。單選按鈕只支援 `check`。                                                                   |
| `dialog`                           | `accept`、`promptText`                                             | 回應待處理的對話框。`accept` 預設為 `false`。                                                                                                                       |

## 等待 [#waiting]

條件成立時，`wait` 立即回傳，否則每 75 ms 再檢查一次。到請求期限前 500 ms 條件仍未成立時，`wait` 以 `wait_timeout` 失敗。即使期限在 500 ms 以內，它也至少檢查一次。期限以 `timeoutMs` 設定，`omw call` 則用 `--timeout-ms`。設定以下其中一個欄位：

| 欄位         | 意義                                                                                      |
| ------------ | ----------------------------------------------------------------------------------------- |
| `selector`   | 第一個符合的元素存在、有邊界框，且不是 `visibility: hidden`。                             |
| `text`       | `document.body.innerText` 包含該字串。                                                    |
| `url`        | 目前的 URL 符合。`*` 可比對任意一段字元。                                                 |
| `expression` | JavaScript 運算式為真值。                                                                 |
| `load`       | `load` 等待 `readyState === "complete"`；`domcontentloaded` 等待文件離開 `loading` 狀態。 |
| `state`      | `visible`（預設）或 `hidden`，後者會反轉條件。                                            |

## 框架 [#frames]

| 動作或引數                                                                  | 意義                                                     |
| --------------------------------------------------------------------------- | -------------------------------------------------------- |
| `frame {"cmd": "list"}`                                                     | 列出框架，含 `id`、`name` 與 `url`，包括跨行程的子框架。 |
| `frame {"selector": "iframe#panel"}`                                        | 選取包含符合之 iframe 元素的框架。                       |
| `frame {"frameId": "..."}`、`frame {"name": "..."}`、`frame {"url": "..."}` | 依 id、名稱或完整 URL 選取。                             |
| `frame {"cmd": "main"}`                                                     | 回到主框架，並丟棄該框架的參照。                         |

選取框架後，頁面動作在該框架中執行。選取框架會丟棄先前的參照，並需要重新取得快照。

框架導覽或被移除時，選取就會結束；在 Chrome 中，分頁的偵錯工作階段結束時也會結束，例如使用者在 Chrome 的偵錯提示上按了取消，或擴充功能的 worker 重新啓動。之後第一個要在該框架執行的動作會以 `frame_unavailable` 失敗一次，再之後的動作使用主框架。

## 檔案與擷取 [#files-and-capture]

| 動作          | 引數                                                                                                                               | 備註                                                                                                                                                                            |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `screenshot`  | `format`（`png`、`jpeg`）、`quality`（0 到 100）、`selector`、`fullPage`、`path`                                                   | 回傳 `path`、`sizeBytes` 與 `mimeType`。沒有 `path` 時，檔案會放在 daemon 的成品目錄下。既有的路徑會被拒絕。                                                                    |
| `save_as_pdf` | `paper_format`（預設 `letter`；另有 `legal`、`a4`、`a3`、`tabloid`）、`landscape`、`scale`（0.1 到 2）、`print_background`、`path` | 以分塊方式把 PDF 串流寫到磁碟，並回傳 `path`、`sizeBytes`、`mimeType` 與 `pageTitle`。僅限 Chrome。                                                                             |
| `upload`      | `selector`、`files`                                                                                                                | 執行瀏覽器之機器上的絕對路徑。Chrome 需要在 `chrome://extensions` 為擴充功能開啓「允許存取檔案網址」。對 Firefox，daemon 會內嵌檔案內容：每個指令 16 MiB，進行中的合計 64 MiB。 |
| `download`    | `url`（HTTP(S)）、`filename`                                                                                                       | 在瀏覽器所在的主機上回傳 `path`、`sizeBytes`、`mimeType` 與 `id`。取消或逾時會中斷下載。                                                                                        |

編碼後的結果超過 32 MiB 的螢幕截圖，會以 `result_too_large` 失敗。

## 網路、主控台、儲存空間與 cookie [#network-console-storage-and-cookies]

| 動作      | 引數                                                                                          | 備註                                                                                                                                                                                                      |
| --------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `network` | `cmd`：`start`、`stop`、`list`、`detail`；`filter`、`requestId`                               | 每個分頁保留最近 500 個請求。`filter` 是 URL 子字串。`detail` 回傳回應本文。在 Chrome 中，記錄範圍是 `start` 時所選的框架：主框架及其同行程的 iframe，或一個跨行程的 iframe。之後選取其他框架不會改變它。 |
| `console` | `cmd`：`start`、`list`、`clear`、`stop`                                                       | 每個分頁最多儲存 200 筆項目，每筆截斷為 8192 個字元。                                                                                                                                                     |
| `storage` | `cmd`：`list`、`get`、`set`、`remove`、`clear`；`kind`（`local`、`session`）、`name`、`value` | 只讀寫目前的來源。回傳 `origin`、`kind`，以及 `value` 或整個儲存空間。                                                                                                                                    |
| `cookies` | `cmd`：`list`、`set`、`delete`、`clear`；`data`、`name`                                       | 範圍限於目前的 URL。`set` 把 `data` 直接傳給 cookie 欄位。                                                                                                                                                |

## 模擬 [#emulation]

| 欄位                          | 意義                                                                         |
| ----------------------------- | ---------------------------------------------------------------------------- |
| `width`、`height`             | 視埠大小，單位為 CSS 像素，各為 1 到 16384。變更裝置度量時，兩者都必須提供。 |
| `deviceScaleFactor`、`mobile` | 度量覆寫所用的裝置像素比與行動裝置旗標。                                     |
| `colorScheme`                 | 供 `prefers-color-scheme` 使用的 `dark` 或 `light`。                         |
| `latitude`、`longitude`       | 地理位置。兩者必須一起提供。                                                 |
| `offline`                     | 讓頁面離線或恢復連線。                                                       |
| `data`                        | 額外的 HTTP 標頭：最多 128 個字串值與 32 KiB，不可含有 CR 或 LF。            |

設定會在工作階段內持續有效，並在新分頁導覽之前套用到它們。Chrome 結束分頁的偵錯工作階段時（例如擴充功能的 worker 重新啓動後）會丟棄這些設定；工作階段的任務分頁收到下一個指令時會再次套用。借用的分頁不在其內。

## 批次 [#batch]

`batch` 接受 `steps`，這是由 `{ action, args }` 物件組成的陣列，含 1 到 64 項。步驟在同一個請求中依序執行，並在第一個錯誤時停止。錯誤保留失敗步驟的錯誤碼，訊息以 `batch step N of M (action):` 開頭，表示第 1 到第 N-1 步已經完成。已完成的步驟不會還原。`batch`、`close_session`、`screenshot`、`save_as_pdf`、`artifact_read` 與 `artifact_close` 不能出現在批次內。

## 預設集 [#presets]

| 欄位          | 意義                                                              |
| ------------- | ----------------------------------------------------------------- |
| `preset`      | `anti-ad`（預設）、`zen` 或 `none`。                              |
| `environment` | 安裝內附的外觀規則與 scriptlet。從下一個文件起套用。              |
| `zen`         | `images`、`fonts`、`css`、`javascript`。`true` 會封鎖該資源類型。 |
| `cmd`         | `status` 讀取該分頁的計數器、攔截與後備原因。                     |

組態儲存在工作階段上，並套用到任務分頁。借用的分頁不在其內。`navigate` 接受相同的欄位，並在導覽開始後儲存它們。請見[頁面預設集](https://oh-my-webbridge.github.io/md/zh-mo/presets/content.md)。

## CDP [#cdp]

`cdp` 對分頁送出一個 Chrome DevTools Protocol 指令：`method`、`params`，以及子目標可選的 `sessionId`。它原封不動地回傳協定結果。

有兩個方法會改變橋接器自身的狀態。`Runtime.disable` 結束其工作階段的框架選擇；沒有 session id 的 `Page.disable` 使該分頁的 `@e` 參照失效；下一次快照或導覽會重新啓用這些事件。

daemon 在內部使用 `cdp_attach`、`cdp_detach`、`artifact_read`、`artifact_close` 與 `list_targets`。不要自行送出它們。

## 選擇器 [#selectors]

每個接受 `selector` 的動作都接受下列形式。

| 形式                             | 範例                                 | 比對方式                                                                 |
| -------------------------------- | ------------------------------------ | ------------------------------------------------------------------------ |
| CSS                              | `button[type=submit]`、`css=.card a` | 選擇器查詢。也會搜尋開啓的 shadow root。                                 |
| `@e` 參照                        | `@e<generation>.<index>`             | 最新 `snapshot` 中的節點。                                               |
| `role=`                          | `role=button[name="Submit"]`         | 無障礙角色，以及可選的名稱。名稱是 JSON 字串，須完全相符。               |
| `text=`                          | `text=Sign in`、`text="Sign in"`     | 轉譯後的文字。未加引號的值比對不分大小寫的子字串；加引號的值須完全相符。 |
| `label=`                         | `label=Email`                        | 關聯的標籤文字或 `aria-label`。                                          |
| `placeholder=`、`alt=`、`title=` | `placeholder=Search`                 | 對應的屬性。                                                             |
| `testid=`                        | `testid=search`                      | `data-testid` 屬性。                                                     |
| `xpath=`                         | `xpath=//table//a`                   | 只在目前文件中執行的 XPath。不會穿越 shadow root。                       |

附加 ` >>nth=0` 取第一個符合項，或附加 ` >>nth=-1` 取最後一個。文字、CSS 與屬性定位器會穿越開啓的 shadow root。它們看不到封閉的 shadow root。

## 參照的存續期間 [#reference-lifetime]

`@e` 參照屬於單一文件世代。每次快照都以新的世代為參照編號，世代是 36 進位的 Snowflake ID。在 Chrome 中，新的快照、框架選擇、新的主文件（導覽或重新載入），或分頁 URL 的變更，都會使它們失效。在所選框架內取得的快照，也會在該框架導覽、重新載入、被移除，或選取結束時過期。其他 iframe 載入或導覽，不影響它的有效性。在 Firefox 中，參照存在於產生它們的文件內；請見 [Firefox](https://oh-my-webbridge.github.io/md/zh-mo/firefox/content.md)。

## 錯誤 [#errors]

每個錯誤都帶有 `code` 與 `message`。HTTP 狀態碼列於下方；這裏未列出的錯誤碼回傳 502。

| 錯誤碼                  | HTTP | 意義                                                                                                                                                                         | 處理方式                                                                                                       |
| ----------------------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `invalid_request`       | 400  | 本文被拒絕：有未知欄位、缺少 action 或 session、工作階段名稱含有不允許的字元、`browser` 無效，或 `timeoutMs` 超出 1 到 120000。                                              | 修正 JSON。訊息會指出欄位。                                                                                    |
| `invalid_args`          | 400  | 引數缺少、型別錯誤，或超出範圍，包括無法解析的選擇器。`screenshot` 或 `save_as_pdf` 的路徑已經存在、它的目錄無法建立或寫入，或它所在的檔案系統無法建立硬連結時，也會被拒絕。 | 閲讀訊息；它會指出動作與引數。                                                                                 |
| `unsupported`           | 501  | 目標瀏覽器沒有這個動作，或沒有它的某個引數。                                                                                                                                 | 不要重試。改用其他動作，或使用 Chrome 工作階段。                                                               |
| `busy`                  | 429  | 容量限制已滿：指令名額、每個工作階段 32 個分頁、每個瀏覽器 128 個工作階段、Firefox 上傳額度，或兩個同時進行的成品工作。也可能是工作階段在指令路由期間改到另一個瀏覽器。      | 降低並行數量，並在先前的指令完成後重試。                                                                       |
| `browser_offline`       | 503  | 目標瀏覽器沒有擴充功能連線，包括綁定到未連線瀏覽器的工作階段。                                                                                                               | 檢查 `omw doctor` 與擴充功能，或在新的工作階段中繼續。                                                         |
| `session_browser`       | 409  | 工作階段綁定到另一個瀏覽器，而請求指定了這個瀏覽器。                                                                                                                         | 移除 `browser`，或關閉該工作階段並開始新的工作階段。                                                           |
| `outcome_unknown`       | 504  | 指令可能已經執行：期限、取消、傳輸寫入或斷線切斷了回覆，或指令執行期間頁面導覽或偵錯器中斷連線。訊息會指出原因。                                                             | 重複之前，先觀察頁面或網路狀態。切勿盲目重送提交、付款或發布操作。                                             |
| `wait_timeout`          | 408  | `wait` 的條件在期限前沒有成立。`wait` 不會變更頁面。                                                                                                                         | 以更長的期限再次送出 `wait`，或檢查條件。                                                                      |
| `tab_busy`              | 409  | 該分頁屬於另一個工作階段。                                                                                                                                                   | 使用這個工作階段持有的分頁，或使用另一個工作階段。                                                             |
| `stale_ref`             | 409  | `@e` 參照比它所屬的文件存活得更久。                                                                                                                                          | 重新取得 `snapshot`。                                                                                          |
| `no_tab`                | 502  | 頁面動作在工作階段還沒有分頁時執行，或在目前分頁以 `close_tab` 以外的方式關閉之後執行。                                                                                      | 執行 `navigate` 或 `find_tab`，或傳入工作階段另一個分頁的 `tabId`。                                            |
| `tab_missing`           | 502  | `find_tab` 沒有符合的分頁，或指令指定的分頁已經關閉。                                                                                                                        | 先在這個工作階段中開啓該頁面，或傳入 `active: true` 借用瀏覽器的使用中分頁。分頁已關閉時，改在另一個分頁繼續。 |
| `restricted_tab`        | 502  | 該分頁不是一般的、非無痕的 HTTP(S) 頁面。                                                                                                                                    | 導覽到 HTTP(S) 頁面。瀏覽器內部頁面無法用指令碼操作。                                                          |
| `borrowed_tab`          | 502  | 動作需要工作階段建立的分頁：關閉它，或對借用的分頁套用預設集。                                                                                                               | 用 `navigate` 開啓任務分頁。                                                                                   |
| `element_missing`       | 502  | 選擇器沒有符合任何元素。                                                                                                                                                     | 檢查選擇器，或重新取得快照。                                                                                   |
| `element_hidden`        | 502  | 元素沒有邊界框，因此沒有可點擊的中心。                                                                                                                                       | 把它捲動到可見範圍，或等待它轉譯完成。                                                                         |
| `element_action_failed` | 502  | 頁面拒絕了這個操作，例如填寫不可編輯的元素，或選取不存在的選項。                                                                                                             | 用 `get` 或 `is` 檢查，並調整動作。                                                                            |
| `state_mismatch`        | 502  | `check` 或 `uncheck` 讓控制項停在錯誤的狀態。                                                                                                                                | 用 `is` 重新讀取，然後重試，或改為點擊它。                                                                     |
| `evaluation_failed`     | 502  | `evaluate` 擲出例外，或內部頁面指令碼擲出例外。在 Firefox 中，也包括結果無法傳回的 `evaluate`，例如 DOM 節點、`Window` 或 `BigInt`；程式碼已經執行。                         | 修正運算式，或傳回一般資料。訊息帶有頁面例外。                                                                 |
| `frame_missing`         | 502  | `frame` 找不到符合所給選擇器、id、名稱或 URL 的框架。                                                                                                                        | 用 `frame {"cmd":"list"}` 列出框架，並選取其中一個。                                                           |
| `frame_unavailable`     | 502  | 所選的框架已被取代、移除或失去其執行環境，或分頁的偵錯工作階段已結束。                                                                                                       | 之後的指令使用主框架；如果工作要在該框架繼續，請重新選取它。                                                   |
| `history_missing`       | 502  | `history back` 或 `forward` 在該方向上沒有項目。                                                                                                                             | 先讀取 `history {"cmd":"list"}`。                                                                              |
| `request_missing`       | 502  | 該請求沒有網路紀錄，或紀錄已被逐出。                                                                                                                                         | 開始記錄，重現問題，然後讀取 `list`。                                                                          |
| `request_pending`       | 502  | 回應本文尚未完整。                                                                                                                                                           | 等 `list` 中出現 `complete: true`，再重試 `detail`。                                                           |
| `request_failed`        | 502  | 請求本身失敗。                                                                                                                                                               | 讀取該項目上的錯誤文字。                                                                                       |
| `body_unavailable`      | 502  | Firefox 沒有保留回應本文：WebSocket、被較新的本文擠出，或回應中斷。                                                                                                          | 開着 `network` 記錄重新送出請求，或從頁面讀取資料。                                                            |
| `download_missing`      | 502  | 瀏覽器沒有列出該下載。                                                                                                                                                       | 重試 `download`。                                                                                              |
| `download_failed`       | 502  | 瀏覽器中斷了下載。                                                                                                                                                           | 閲讀訊息並重試。                                                                                               |
| `file_access_required`  | 502  | Chrome 的 `upload` 需要擴充功能的「允許存取檔案網址」開關，而它預設為關閉。                                                                                                  | 在 `chrome://extensions` 找到 oh-my-webbridge，開啓「允許存取檔案網址」後重試。                                |
| `window_failed`         | 502  | 新視窗沒有分頁。                                                                                                                                                             | 重試 `window_new`。                                                                                            |
| `result_too_large`      | 502  | 結果在傳輸時超過 32 MiB、儲存的螢幕截圖或 PDF 超過 100 MiB，或網路本文在 Chrome 中超過 2 Mi 個字元、在 Firefox 中超過 1 MiB。                                                | 縮小結果：螢幕截圖使用 `selector` 或 `jpeg`，並讀取較小的片段。                                                |
| `debugger_unavailable`  | 502  | Chrome 拒絕附加偵錯工具，例如因為 DevTools 已開啓，或原則封鎖了它。                                                                                                          | 關閉該分頁的 DevTools 並重試。                                                                                 |
| `browser_error`         | 502  | 擴充功能回報了沒有錯誤碼的錯誤。                                                                                                                                             | 閲讀訊息，重試一次，然後回報。                                                                                 |
| `internal`              | 502  | daemon 端的失敗，例如編碼請求時出錯。                                                                                                                                        | 重試。如果持續發生，重新啓動 daemon。                                                                          |
