n8n-binary-and-data

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

n8n Binary and Data

n8n 二进制与数据

Every n8n item carries two independent slots:
$json
for structured data and
$binary
for file bytes. They travel side by side through the workflow. File contents — the actual PDF, image, or zip — live in
$binary
, never in
$json
. Get that split wrong and you read an empty field, lose a file mid-flow, or hand an AI agent a tool input it can't use.
This skill covers where binary lives, how to read and write it, how to keep it from being silently stripped, the hard wall between binary and the AI-agent tool boundary, and why chat surfaces need a URL instead of raw bytes.

每个n8n条目都包含两个独立的存储区:
$json
用于结构化数据,
$binary
用于文件字节。它们在工作流中并行传递。文件内容——实际的PDF、图片或压缩包——存储在
$binary
中,绝不会出现在
$json
里。如果混淆了这两者,你会读取到空字段、在工作流中途丢失文件,或是给AI Agent传递无法使用的工具输入。
本技能涵盖了二进制数据的存储位置、读写方法、如何防止其被静默移除、二进制数据与AI Agent工具边界的严格限制,以及为何聊天界面需要URL而非原始字节。

The three rules that prevent 90% of binary bugs

避免90%二进制错误的三条规则

  1. File contents are in
    $binary
    , not
    $json
    .
    After an HTTP download, a "Read Files", or an email-attachment trigger, the bytes sit in
    $binary.<key>
    .
    $json
    holds metadata at most. Reading
    $json.data
    for file contents gives you nothing.
  2. Binary cannot cross the AI-agent tool boundary — in either direction. Tool arguments and tool return values are JSON only. An uploaded image can't be passed into a tool as a file, and a tool can't return raw bytes. Pre-stage to storage and pass a key or URL through JSON instead. See
    AGENT_TOOL_BINARY.md
    .
  3. Chat surfaces render images by URL, not by
    $binary
    .
    Slack, Discord, Teams, Telegram, embedded webhook chat — none of them read the binary slot. The image has to live somewhere a URL can fetch it. See
    CDN_REQUIREMENT.md
    .

  1. 文件内容存储在
    $binary
    中,而非
    $json
    在HTTP下载、“读取文件”或邮件附件触发后,字节数据会存放在
    $binary.<key>
    中。
    $json
    最多仅包含元数据。读取
    $json.data
    获取文件内容只会得到空值。
  2. 二进制数据无法跨越AI Agent工具边界——无论方向如何。 工具参数和返回值仅支持JSON格式。上传的图片无法作为文件传入工具,工具也无法返回原始字节数据。应先将数据预存到存储服务中,再通过JSON传递密钥或URL。详见
    AGENT_TOOL_BINARY.md
  3. 聊天界面通过URL渲染图片,而非
    $binary
    Slack、Discord、Teams、Telegram、嵌入式webhook聊天——这些平台都不会读取二进制存储区。图片必须存储在可通过URL访问的位置。详见
    CDN_REQUIREMENT.md

The two slots

两个存储区

Each item is shaped like this:
json
{
  "json": { "customerId": 42, "status": "sent" },
  "binary": {
    "invoice": {
      "data": "<base64-encoded bytes>",
      "mimeType": "application/pdf",
      "fileName": "invoice-42.pdf",
      "fileExtension": "pdf"
    }
  }
}
The key inside
binary
(
invoice
here) is the binary property name. Most file-handling nodes have a
binaryPropertyName
parameter that points at it — the producer names the slot, the consumer references it by that name. The default key across most nodes is
data
, so when nothing tells you otherwise, assume
$binary.data
.
$json
and
$binary
are separate namespaces. An expression like
{{ $binary.invoice.fileName }}
reads file metadata;
{{ $json.customerId }}
reads data. They never mix.
This split also explains a webhook gotcha: a Webhook trigger receiving
multipart/form-data
puts the uploaded file in
$binary
and the accompanying form fields in
$json.body
— so an uploaded file is not somewhere under
$json
at all. (The
$json.body
nesting for webhooks is n8n-expression-syntax territory.)
See
BINARY_BASICS.md
for the full slot anatomy, mime types, and size limits.

每个条目的结构如下:
json
{
  "json": { "customerId": 42, "status": "sent" },
  "binary": {
    "invoice": {
      "data": "<base64-encoded bytes>",
      "mimeType": "application/pdf",
      "fileName": "invoice-42.pdf",
      "fileExtension": "pdf"
    }
  }
}
binary
中的键(此处为
invoice
)是二进制属性名称。大多数文件处理节点都有一个
binaryPropertyName
参数指向该键——生成节点命名存储区,消费节点通过该名称引用它。大多数节点的默认键为
data
,因此若无特殊说明,默认使用
$binary.data
$json
$binary
是独立的命名空间。表达式
{{ $binary.invoice.fileName }}
用于读取文件元数据;
{{ $json.customerId }}
用于读取结构化数据。二者永远不会混合。
这种区分也解释了webhook的一个陷阱:接收
multipart/form-data
的Webhook触发器会将上传的文件放入
$binary
,将附带的表单字段放入
$json.body
——因此上传的文件根本不在
$json
下。(webhook的
$json.body
嵌套属于n8n-expression-syntax范畴。)
有关存储区完整结构、MIME类型和大小限制,请参阅
BINARY_BASICS.md

Producing binary

生成二进制数据

You rarely build a
$binary
slot by hand — nodes populate it for you:
SourceHow binary appears
HTTP Request with
responseFormat: "file"
Response body lands in
$binary.data
(or the name you set)
Read/Write Files from DiskFile contents read into
$binary
Storage downloads (S3, Google Drive, Dropbox, etc.)Downloaded file in
$binary.<key>
Email triggers with attachmentsEach attachment arrives in
$binary
Provider AI media nodes (image/audio gen)Set
options.binaryPropertyOutput
so the bytes land where the next node looks
For an HTTP download, the one field that matters is
responseFormat
. Confirm it with
get_node
on
nodes-base.httpRequest
— leaving it as the default JSON/string format is the classic reason a downloaded file ends up as garbled text in
$json
instead of clean bytes in
$binary
.

你很少需要手动构建
$binary
存储区——节点会自动为你填充:
来源二进制数据的呈现方式
设置
responseFormat: "file"
的HTTP请求
响应体存入
$binary.data
(或你设置的名称)
从磁盘读取/写入文件文件内容读取到
$binary
存储服务下载(S3、Google Drive、Dropbox等)下载的文件存入
$binary.<key>
带附件的邮件触发器每个附件都存入
$binary
供应商AI媒体节点(图像/音频生成)设置
options.binaryPropertyOutput
,使字节数据存入下一个节点预期的位置
对于HTTP下载,关键字段是
responseFormat
。请通过
get_node
查看
nodes-base.httpRequest
的设置——若保留默认的JSON/字符串格式,下载的文件会以乱码文本形式出现在
$json
中,而非干净的字节数据存入
$binary
,这是典型错误。

Reading and writing binary in a Code node

在Code节点中读写二进制数据

Most workflows never need to crack open the bytes — they just pass binary through to a consumer (email attachment, file upload, Slack file). When you do need the raw bytes, do it in a Code node.
Read with
getBinaryDataBuffer
— do not try to base64-decode
$binary.<key>.data
by hand:
javascript
// Code node, "Run Once for Each Item"
const buffer = await this.helpers.getBinaryDataBuffer(0, 'data'); // (itemIndex, propertyName)
const text = buffer.toString('utf-8');
const length = buffer.length;

return [{
  json: { ...$json, length },
  binary: $input.item.binary,   // pass the binary through, or it's gone
}];
Write by building the slot yourself — base64 the bytes plus a mime type and file name:
javascript
const text = 'Hello, world!';
return [{
  json: { ok: true },
  binary: {
    report: {
      data: Buffer.from(text).toString('base64'),
      mimeType: 'text/plain',
      fileName: 'report.txt',
      fileExtension: 'txt',
    },
  },
}];
The Code-node sandbox, helpers, and execution modes are the domain of n8n-code-javascript (and n8n-code-python) — use those for the language-level detail. The one binary-specific thing to remember here: a Code node that returns
[{ json: {...} }]
without re-attaching
binary
silently drops the file. See
BINARY_BASICS.md
.

大多数工作流无需直接处理字节数据——只需将二进制数据传递给消费节点(邮件附件、文件上传、Slack文件)。当你确实需要原始字节数据时,请在Code节点中操作。
读取使用
getBinaryDataBuffer
——请勿尝试手动对
$binary.<key>.data
进行base64解码:
javascript
// Code node, "Run Once for Each Item"
const buffer = await this.helpers.getBinaryDataBuffer(0, 'data'); // (itemIndex, propertyName)
const text = buffer.toString('utf-8');
const length = buffer.length;

return [{
  json: { ...$json, length },
  binary: $input.item.binary,   // pass the binary through, or it's gone
}];
写入需自行构建存储区——将字节数据进行base64编码,并添加MIME类型和文件名:
javascript
const text = 'Hello, world!';
return [{
  json: { ok: true },
  binary: {
    report: {
      data: Buffer.from(text).toString('base64'),
      mimeType: 'text/plain',
      fileName: 'report.txt',
      fileExtension: 'txt',
    },
  },
}];
Code节点的沙箱、辅助函数和执行模式属于n8n-code-javascript(以及n8n-code-python)的范畴——这些技能负责语言层面的细节。此处需要记住的二进制数据特定规则:若Code节点返回
[{ json: {...} }]
但未重新附加
binary
,则会静默丢失文件。详见
BINARY_BASICS.md

Keeping binary alive across transforms

在转换过程中保留二进制数据

JSON-only nodes — Edit Fields (Set), Code, IF, and others — can drop the
$binary
slot from their output. The workflow validates clean and runs without error; the file just isn't there downstream when the email node goes to attach it.
Two ways to keep it:
  • Pass-through option on the transforming node. Edit Fields has
    includeOtherFields
    ; a Code node can return
    binary: $input.item.binary
    explicitly. Cheapest fix when it's available.
  • Fan out and Merge by position. Route the source into both the transform and a bypass branch, then recombine with a Merge in
    combineByPosition
    mode. The JSON comes from the transform side, the binary survives on the bypass side.
[Source with binary] ─┬─→ [Edit Fields: change JSON] ─┐
                      │      (binary stripped here)     ├─→ [Merge: combineByPosition] ─→ [Email: attach]
                      └──────────────────────────────────┘
                          (bypass — binary passes through untouched)
combineByPosition
pairs item N from each input, so the field counts must line up. The connection wiring and the alternatives for many-strip-point chains (upload-early, sub-workflow) are in
MERGE_FOR_CONTEXT.md
.

仅处理JSON的节点——编辑字段(设置)、Code、IF等——可能会从输出中移除
$binary
存储区。工作流会正常验证并运行,但当下游邮件节点尝试附加文件时,文件已不存在。
有两种方法可以保留二进制数据:
  • 转换节点的传递选项。编辑字段节点有
    includeOtherFields
    选项;Code节点可显式返回
    binary: $input.item.binary
    。若该选项可用,这是最简单的修复方法。
  • 分支输出并按位置合并。将源节点同时路由到转换分支和旁路分支,然后使用Merge节点的
    combineByPosition
    模式重新组合。JSON数据来自转换分支,二进制数据通过旁路分支保留。
[Source with binary] ─┬─→ [Edit Fields: change JSON] ─┐
                      │      (binary stripped here)     ├─→ [Merge: combineByPosition] ─→ [Email: attach]
                      └──────────────────────────────────┘
                          (bypass — binary passes through untouched)
combineByPosition
会将每个输入中的第N个条目配对,因此条目数量必须一致。连接方式以及多节点移除场景的替代方案(提前上传、子工作流)详见
MERGE_FOR_CONTEXT.md

The agent-tool binary boundary

Agent工具的二进制边界

This is the sharpest edge. An AI Agent talks to its tools (Custom Code Tool, Call n8n Workflow Tool, HTTP Request Tool, MCP tools) over JSON. Binary does not fit through that pipe in either direction. The fix is the same shape both ways: stage the bytes in storage, pass a key/URL through JSON, fetch on the other side.
Inbound — a user uploads a file the agent's tool must operate on:
  1. The chat trigger gives you a
    files[]
    array. Split it out and upload each file to private storage under a hashed key.
  2. Re-merge that branch before the agent runs (it's a synchronization barrier, not decoration), and set
    executeOnce: true
    on the agent so N files don't trigger N agent runs.
  3. Inject the keys into the agent's system prompt, listing both the original name (human context) and the storage key (what the tool needs), with an explicit "use EXACTLY this key".
  4. The tool receives the key as a string argument and downloads the file from storage itself.
Outbound — a tool generates a file the agent must return:
  1. The tool sub-workflow generates the binary, uploads it to storage, and returns JSON like
    { "ok": true, "key": "...", "url": "https://...", "mimeType": "image/png" }
    .
  2. The agent embeds the URL in its reply (or passes the key to another tool).
passthroughBinaryImages: true
on the agent only changes what the LLM sees for vision — it does not let tools receive the file, and it's image-only (no PDFs, audio, or video). You still need the upload-and-pass-key pattern for any tool. Full patterns, hash strategy, storage choices, and the long-running-tool variant are in
AGENT_TOOL_BINARY.md
.
Building the tool itself? See n8n-code-tool for the Custom Code Tool contract and n8n-workflow-patterns for the AI-Agent-with-tools shape.

这是最严格的限制。AI Agent通过JSON与工具(自定义代码工具、调用n8n工作流工具、HTTP请求工具、MCP工具)通信。二进制数据无法通过这条管道传递,无论方向如何。解决方法都是相同的:将字节数据预存到存储服务中,通过JSON传递密钥/URL,在另一端获取数据
Inbound — a user uploads a file the agent's tool must operate on:
  1. 聊天触发器会返回
    files[]
    数组。拆分该数组,并将每个文件上传到私有存储服务,使用哈希密钥命名。
  2. 在Agent运行前重新合并该分支(这是同步屏障,而非装饰),并在Agent节点设置
    executeOnce: true
    ,避免N个文件触发N次Agent运行。
  3. 将密钥注入Agent的系统提示词,同时列出原始文件名(供人类参考)和存储密钥(工具所需),并明确说明“必须使用此确切密钥”。
  4. 工具接收字符串形式的密钥,并自行从存储服务下载文件。
Outbound — a tool generates a file the agent must return:
  1. 工具子工作流生成二进制数据,上传到存储服务,并返回类似
    { "ok": true, "key": "...", "url": "https://...", "mimeType": "image/png" }
    的JSON。
  2. Agent将URL嵌入回复中(或传递密钥给另一个工具)。
passthroughBinaryImages: true
on the agent only changes what the LLM sees for vision — it does not let tools receive the file, and it's image-only (no PDFs, audio, or video). You still need the upload-and-pass-key pattern for any tool. Full patterns, hash strategy, storage choices, and the long-running-tool variant are in
AGENT_TOOL_BINARY.md
.
Building the tool itself? See n8n-code-tool for the Custom Code Tool contract and n8n-workflow-patterns for the AI-Agent-with-tools shape.

The CDN requirement for chat surfaces

聊天界面的CDN要求

When a workflow generates an image and the user wants it shown inside a chat message:
  • Binary on the item isn't enough. The chat client renders messages that reference images by URL (or pushes bytes through the platform's own file-upload API). It never reads
    $binary
    .
  • The bytes have to live somewhere a URL can fetch over HTTPS. Upload to an object store or drive first, then embed the returned URL.
  • n8n has no built-in CDN. The user provides the storage.
Ask which storage they already use rather than defaulting to S3 — object storage (S3, R2, GCS, Azure Blob, Backblaze B2, Supabase Storage) and drive-style services (Dropbox, Google Drive, OneDrive, Box) all work and all change the URL shape. Cloudflare R2 is the lowest-friction starting point if they have nothing. For sensitive content, use a signed URL with an expiry rather than a permanently public one. See
CDN_REQUIREMENT.md
.

当工作流生成图片并需要在聊天消息中显示时:
  • Binary on the item isn't enough. 聊天客户端通过URL引用图片来渲染消息(或通过平台自身的文件上传API传递字节数据)。它永远不会读取
    $binary
  • The bytes have to live somewhere a URL can fetch over HTTPS. 先上传到对象存储或云盘,再嵌入返回的URL。
  • n8n has no built-in CDN. 存储服务由用户提供。
Ask which storage they already use rather than defaulting to S3 — object storage (S3, R2, GCS, Azure Blob, Backblaze B2, Supabase Storage) and drive-style services (Dropbox, Google Drive, OneDrive, Box) all work and all change the URL shape. Cloudflare R2 is the lowest-friction starting point if they have nothing. For sensitive content, use a signed URL with an expiry rather than a permanently public one. See
CDN_REQUIREMENT.md
.

What's NOT available

不可用功能

  • $fromAI()
    cannot carry binary.
    It fills tool parameters with strings, numbers, booleans, and objects — never file bytes. Pass a storage key instead.
  • Tool arguments and returns are JSON only. There is no "binary parameter" on an agent tool, in or out.
  • n8n ships no CDN or public file host. Serving a file over a URL is always something the user's storage does, not n8n.
  • getBinaryDataBuffer
    is a Code-node helper.
    It isn't available in the Custom Code Tool sandbox (see n8n-code-tool).

  • $fromAI()
    cannot carry binary.
    它仅用字符串、数字、布尔值和对象填充工具参数——绝不会包含文件字节。请传递存储密钥替代。
  • Tool arguments and returns are JSON only. Agent工具没有“二进制参数”,无论输入还是输出。
  • n8n ships no CDN or public file host. 通过URL提供文件始终由用户的存储服务完成,而非n8n。
  • getBinaryDataBuffer
    is a Code-node helper.
    它在自定义代码工具沙箱中不可用(请参阅n8n-code-tool)。

Where Data Tables live

数据表的位置

For persistent tabular storage — reference-counting staged files, tracking which keys are live, dedup — that's the
n8n_manage_datatable
surface, owned by n8n-mcp-tools-expert. This skill does not cover Data Tables.

对于持久化表格存储——引用计数预存文件、跟踪有效密钥、去重——属于
n8n_manage_datatable
范畴,由n8n-mcp-tools-expert负责。本技能不涵盖数据表。

Anti-patterns

反模式

Anti-patternWhat goes wrongFix
Reading file contents from
$json
Bytes live in
$binary
;
$json
is empty or metadata only
Read
$binary.<key>
, or
getBinaryDataBuffer
in a Code node
HTTP download without
responseFormat: "file"
Bytes arrive as mangled text in
$json
, not clean binary
Set
responseFormat: "file"
on the HTTP Request node
Code node returns
[{json:{...}}]
, no
binary
The file is silently dropped downstreamRe-attach
binary: $input.item.binary
in the return
JSON transform (Edit Fields/IF) eats the binaryEmail/upload node finds nothing to attachPass-through option, or fan out + Merge by position
Passing an uploaded file into a tool via
$fromAI
$fromAI
can't carry binary; the tool gets nothing
Pre-stage to storage, inject the key in the system prompt, tool fetches by key
Assuming
passthroughBinaryImages
lets tools see the file
It only affects what the LLM sees, and only for imagesStill need the upload-and-pass-key pattern for tools
Tool returns raw binary to the agentTool output is JSON; bytes don't survive (and bloat context)Upload, return
{ key, url }
in JSON
Posting
$binary
to a chat surface and expecting an image
Chat clients render by URL, not raw bytesUpload to storage/CDN, embed the URL or use the platform file API
Hardcoding base64 in a Code nodeHuge workflow JSON, slow, leakyReference via
$binary
, or upload and reference by URL

反模式问题所在修复方案
$json
读取文件内容
字节数据存储在
$binary
中;
$json
为空或仅含元数据
读取
$binary.<key>
,或在Code节点中使用
getBinaryDataBuffer
HTTP下载未设置
responseFormat: "file"
字节数据以乱码文本形式出现在
$json
中,而非干净的二进制数据
在HTTP请求节点设置
responseFormat: "file"
Code节点返回
[{json:{...}}]
,未包含
binary
文件在下游被静默丢失在返回时重新附加
binary: $input.item.binary
JSON转换(编辑字段/IF)移除二进制数据邮件/上传节点找不到可附加的文件使用传递选项,或分支输出 + 按位置合并
通过
$fromAI
将上传文件传入工具
$fromAI
无法携带二进制数据;工具无法获取内容
预存到存储服务,在系统提示词中注入密钥,工具通过密钥获取文件
认为
passthroughBinaryImages
可让工具访问文件
它仅影响LLM的视觉输入,且仅适用于图片工具仍需使用上传并传递密钥的模式
工具向Agent返回原始二进制数据工具输出为JSON;字节数据无法保留(且会膨胀上下文)上传到存储服务,返回
{ key, url }
格式的JSON
$binary
发送到聊天界面并期望显示图片
聊天客户端通过URL渲染,而非原始字节数据上传到存储/CDN,嵌入URL或使用平台文件API
在Code节点中硬编码base64工作流JSON体积庞大、运行缓慢、易泄露通过
$binary
引用,或上传后通过URL引用

Reference files

参考文件

FileRead when
BINARY_BASICS.md
First time handling binary, or reading/writing the
$binary
slot, mime types, size limits
AGENT_TOOL_BINARY.md
An agent tool needs an uploaded file, or produces one — the boundary in either direction
MERGE_FOR_CONTEXT.md
Binary disappears after a JSON transform and you need to re-attach it
CDN_REQUIREMENT.md
Showing images in a chat surface or anywhere that needs URL-referenced images

文件阅读场景
BINARY_BASICS.md
首次处理二进制数据,或读写
$binary
存储区、MIME类型、大小限制
AGENT_TOOL_BINARY.md
Agent工具需要处理上传文件或生成文件——双向边界场景
MERGE_FOR_CONTEXT.md
JSON转换后二进制数据丢失,需要重新附加
CDN_REQUIREMENT.md
在聊天界面或其他需要URL引用图片的场景显示图片

Integration with Other Skills

与其他技能的集成

n8n-code-javascript / n8n-code-python: the Code node is where you read/write raw bytes (
getBinaryDataBuffer
,
Buffer.from(...).toString('base64')
). Those skills own the sandbox, helpers, and execution-mode detail — this skill owns the rule that binary must be re-attached on return.
n8n-code-tool: the Custom Code Tool sandbox is narrower — no
$binary
, no
getBinaryDataBuffer
, no
$fromAI
. When a tool needs a file, this skill's storage-key pattern is how it gets one.
n8n-workflow-patterns: the agent-tool binary boundary sits inside the AI-Agent-with-tools pattern; the CDN flow is a generate → upload → reply chain.
n8n-node-configuration:
responseFormat
,
binaryPropertyName
,
includeOtherFields
,
binaryPropertyOutput
are all conditional fields — use
get_node
to confirm the exact names on the user's version.
n8n-expression-syntax: addressing
$binary.<key>.fileName
vs
$json.body
(webhook uploads in particular) is expression territory.
n8n-validation-expert: a dropped binary slot is a silent failure —
validate_workflow
won't flag it. Confirm presence by inspecting the execution.
n8n-mcp-tools-expert: owns
n8n_manage_datatable
(Data Tables) and
n8n_executions
— use the latter to confirm a
binary
slot actually survived a given node.
n8n-error-handling: storage uploads and downloads fail; the inbound/outbound staging steps need error branches so a missing key doesn't 404 silently.
using-n8n-mcp-skills: the index of how these skills fit together.

n8n-code-javascript / n8n-code-python:Code节点是读取/写入原始字节数据的位置(
getBinaryDataBuffer
Buffer.from(...).toString('base64')
)。这些技能负责沙箱、辅助函数和执行模式的细节——本技能负责二进制数据必须在返回时重新附加的规则。
n8n-code-tool:自定义代码工具沙箱的范围更窄——无
$binary
、无
getBinaryDataBuffer
、无
$fromAI
。当工具需要文件时,本技能的存储密钥模式是解决方案。
n8n-workflow-patterns:Agent工具的二进制边界属于带工具的AI Agent模式;CDN流程是生成→上传→回复的链条。
n8n-node-configuration
responseFormat
binaryPropertyName
includeOtherFields
binaryPropertyOutput
均为条件字段——使用
get_node
确认用户版本的准确名称。
n8n-expression-syntax:引用
$binary.<key>.fileName
$json.body
(尤其是webhook上传)属于表达式范畴。
n8n-validation-expert:二进制存储区被移除是静默故障——
validate_workflow
不会标记它。需通过检查执行记录确认其存在。
n8n-mcp-tools-expert:负责
n8n_manage_datatable
(数据表)和
n8n_executions
——使用后者确认
binary
存储区是否在特定节点后保留。
n8n-error-handling:存储服务的上传和下载可能失败;入站/出站预存步骤需要错误分支,避免密钥缺失导致静默404错误。
using-n8n-mcp-skills:这些技能如何协同工作的索引。

Verifying binary survived

验证二进制数据是否保留

Validation won't catch a stripped binary slot — it's a silent failure. Confirm it ran correctly:
  1. n8n_test_workflow
    (or trigger a real run) to produce an execution.
  2. n8n_executions
    to pull that execution, and inspect per-node output for the
    binary
    slot — it shows presence and metadata even if the base64 is too large to render.
  3. The node where
    binary
    last appears is the node before the strip. That's where the pass-through or Merge goes.

验证不会捕获二进制存储区被移除的情况——这是静默故障。请按以下步骤确认运行正确:
  1. 使用
    n8n_test_workflow
    (或触发真实运行)生成执行记录。
  2. 使用
    n8n_executions
    获取该执行记录,检查每个节点的输出是否包含
    binary
    存储区——即使base64数据过大无法显示,也会显示其存在和元数据。
  3. binary
    最后出现的节点是移除前的节点。此处需要添加传递选项或Merge节点。

Quick Reference Checklist

快速参考清单

  • File contents read from
    $binary.<key>
    — never
    $json
  • HTTP downloads use
    responseFormat: "file"
  • Code nodes re-attach
    binary
    on return when the file must continue
  • JSON transforms either pass binary through or Merge it back (
    combineByPosition
    )
  • No attempt to pass binary into/out of an agent tool — keys/URLs through JSON instead
  • passthroughBinaryImages
    used only for LLM vision, not as a tool channel
  • Chat-surface images uploaded to storage; the URL is embedded, not the bytes
  • Storage backend chosen with the user (not defaulted to S3); signed URLs for sensitive content
  • Binary presence confirmed by inspecting the execution, not by validation

Remember: two slots, side by side. Data rides in
$json
, files ride in
$binary
— and the moment a file has to cross an agent tool or reach a chat surface, it travels as a URL, not as bytes.
  • 文件内容从
    $binary.<key>
    读取——绝不从
    $json
    读取
  • HTTP下载使用
    responseFormat: "file"
  • 当文件需要继续传递时,Code节点在返回时重新附加
    binary
  • JSON转换要么传递二进制数据,要么通过
    combineByPosition
    合并回来
  • 不尝试将二进制数据传入/传出Agent工具——通过JSON传递密钥/URL替代
  • passthroughBinaryImages
    仅用于LLM视觉输入,而非工具通道
  • 聊天界面图片上传到存储服务;嵌入URL而非字节数据
  • 根据用户情况选择存储后端(不默认S3);敏感内容使用签名URL
  • 通过检查执行记录确认二进制数据存在,而非仅依赖验证

记住:两个存储区并行存在。结构化数据在
$json
中,文件在
$binary
中——当文件需要跨越Agent工具或到达聊天界面时,它以URL形式传递,而非字节数据。