Problem
Calling Node#select_file can crash the browser tab with:
ERROR:content/browser/bad_message.cc:29 Terminating renderer for bad IPC message, reason 2
Reason 2 corresponds to RFH_CAN_ACCESS_FILES_OF_PAGE_STATE — Chrome's security check that verifies the renderer process has been granted read access to files referenced in page state.
Root cause
Ferrum's Node#select_file uses nodeId to identify the element:
# lib/ferrum/node.rb:113
page.command("DOM.setFileInputFiles", slowmoable: true, nodeId: node_id, files: Array(value))
DOM.setFileInputFiles with nodeId can fail to properly grant the renderer process read access to the specified files. When Chrome later serializes page state containing the file reference, the access check fails and the renderer is killed.
This is particularly reproducible after same-document navigations (e.g. Turbo Drive in Rails apps), where the nodeId may reference a stale DOM context.
Fix
Using backendNodeId instead of nodeId resolves the crash. The backendNodeId is already available via description["backendNodeId"]:
def select_file(value)
files = Array(value).map { |f| File.expand_path(f) }
page.command("DOM.setFileInputFiles", slowmoable: true,
backendNodeId: description["backendNodeId"],
files: files)
end
For reference, Puppeteer uses objectId (not nodeId) for this CDP command, which is why Puppeteer-based tools don't hit this issue.
Environment
- Ferrum: 0.17.1
- Cuprite: 0.17
- Chromium: 145.0.7632.45
- macOS (Darwin 25.3.0)
- Ruby 4.0.1
Problem
Calling
Node#select_filecan crash the browser tab with:Reason 2 corresponds to
RFH_CAN_ACCESS_FILES_OF_PAGE_STATE— Chrome's security check that verifies the renderer process has been granted read access to files referenced in page state.Root cause
Ferrum's
Node#select_fileusesnodeIdto identify the element:DOM.setFileInputFileswithnodeIdcan fail to properly grant the renderer process read access to the specified files. When Chrome later serializes page state containing the file reference, the access check fails and the renderer is killed.This is particularly reproducible after same-document navigations (e.g. Turbo Drive in Rails apps), where the
nodeIdmay reference a stale DOM context.Fix
Using
backendNodeIdinstead ofnodeIdresolves the crash. ThebackendNodeIdis already available viadescription["backendNodeId"]:For reference, Puppeteer uses
objectId(notnodeId) for this CDP command, which is why Puppeteer-based tools don't hit this issue.Environment