Code Node (v1.94.1 Docker) - Output Drops binary Property, $helpers Undefined, & No console.log in Docker Logs

Hello n8n Community,

I’m running a self-hosted n8n instance (version 1.94.1, upgraded from 1.93.0) via Docker on a Linode server (Ubuntu 24.04.2). My server resources (CPU, RAM, disk) are healthy, Docker is running fine, and the n8n container itself is not resource-constrained.

I’m facing a persistent and interconnected set of issues with a Code node that’s intended to process webhook data, create a binary representation of it (for archiving), and then pass both JSON and binary data to subsequent nodes.

Core Problems:

  1. Code Node Silently Drops binary Property from Output:
  • My Code node (named Convert Raw JSON to Binary, set to “Run Once for Each Item”) is scripted to return a single object: return { json: { /* data */ }, binary: { binaryFileContent: { data: "base64string", fileName: "...", mimeType: "..." } } };
  • When I inspect this Code node’s OUTPUT in the n8n UI (JSON tab) after it executes (with a green tick), only the json property and its contents appear. The entire top-level binary property is missing.
  • This happens even with extremely simplified scripts returning a hardcoded binary property.
  • A downstream “ReadWriteFile” node (configured with “Input Binary Field” as binaryFileContent) then fails, typically with “This operation expects the node’s input data to contain a binary file ‘binaryFileContent’, but none was found [item 0]”.
  1. $helpers Object is Undefined in Code Node (v1.94.1):
  • When attempting to use await $helpers.prepareBinaryData(...) within the Code node (in either “Run Once for Each Item” or “Run Once for All Items” mode), the script errors out or enters a catch block, with the error message indicating that "$helpers is not defined".
  • This was confirmed by adding debug fields to the json part of the script’s output (which does appear in the UI).
  1. console.log (and error/warn) from Code Node Script Not Appearing in Docker Logs:
  • Despite adding numerous console.log, console.error, and console.warn statements at various points in the Code node script (including at the very beginning), these messages do not appear in the output of sudo docker logs n8n-n8n-1 --tail 500 on the Linode server immediately after triggering the workflow.
  • The Docker logs show n8n system startup messages and sometimes historical errors from other nodes if they fail, but not the live console.log output from the Code node’s script itself during that specific execution. This makes debugging the script’s internal state very difficult.
  • The Code node itself gets a green tick in the n8n UI, suggesting it executed without an unhandled JavaScript exception visible to n8n’s core executor.

What We’ve Ruled Out / Confirmed:

  • Workflow Trigger: The workflow is being triggered successfully by a PowerShell Invoke-RestMethod call to the production webhook URL. New executions appear in the n8n UI, and the Webhook node gets a green tick.
  • Script Saving: I am explicitly saving the workflow in the n8n UI after every script change in the Code node.
  • Server-Side File Permissions (for the target archive path): While the Archive RawWebhookData node fails because it doesn’t receive the binaryFileContent, tests from inside the n8n Docker container (using docker exec -it n8n-n8n-1 /bin/sh and then touch /path/to/file) confirm that the node user (UID 1000) can create files in the target mapped volume directory (/home/node/.n8n/thxnews_archives/raw_input/). The host directory /opt/n8n/data/thxnews_archives/raw_input/ is owned by UID 1000 with rwx permissions.
  • Successful Archive (once, to /tmp/): There was one previous execution (on v1.93.0, I believe, though I’m now on v1.94.1) where the Archive RawWebhookData node did get a green tick when its path was temporarily set to /tmp/somefile.json. This suggests that if the binary data is correctly passed from the Code node, the archive node can write it. However, I have not been able to reliably reproduce the Code node successfully outputting the binary property since, even with the /tmp/ path.
  • Code Node Modes: The issue of the binary property being dropped from the output (and $helpers being undefined) has been observed in both “Run Once for Each Item” (returning a single object) and “Run Once for All Items” (returning an array of objects, with each object intended to have json and binary properties) modes.
  • Script Logic for Object Construction: Using a debugging script that embeds diagnostic info into the json property of the returned object (since console.log to Docker isn’t visible), I was able to confirm that inside the script, just before the return statement, the object being returned is correctly constructed with both json and binary top-level keys. The binary key and its contents are lost after the return.

Current Script in Convert Raw JSON to Binary (set to “Run Once for Each Item”, based on recent tests where the json part of the debug output was visible):

`JavaScript// Code Node: Convert Raw JSON to Binary (Debug output in JSON)

const item = $input.item;

let debugLog = {
  step: "0_start",
  inputItemJsonDefined: (item && item.json !== undefined),
  helpers_available_test: (typeof $helpers !== 'undefined' && $helpers !== null) ? "Yes" : "No ($helpers is " + typeof $helpers + ")"
};

try {
  if (!item || !item.json) {
    debugLog.step = "1_error_bad_input";
    return { json: { error: "Input item or item.json was undefined.", debug: debugLog } };
  }
  debugLog.inputItemJsonBody = JSON.parse(JSON.stringify(item.json.body || "no body"));

  const dataToArchiveInFile = item.json;
  let jsonStringToArchiveInFile = JSON.stringify(dataToArchiveInFile, null, 2);
  debugLog.step = "2_jsonStringToArchiveInFile_created";

  const bufferForFile = Buffer.from(jsonStringToArchiveInFile, 'utf8');
  debugLog.step = "3_bufferForFile_created";
  
  let binaryDataForOutputFile;
  // Fallback since $helpers is undefined
  debugLog.step = "4_using_manual_base64_fallback";
  binaryDataForOutputFile = {
    data: bufferForFile.toString('base64'),
    mimeType: 'application/json',
    fileName: 'webhook_payload_manual.json'
  };
  debugLog.manual_binary_object_created = JSON.parse(JSON.stringify(binaryDataForOutputFile));


  const outputJsonPortion = {
    originalWebhookBody: item.json.body || {},
    message: "Debug data included. $helpers was " + debugLog.helpers_available_test,
    fallback_binary_fileName: binaryDataForOutputFile.fileName
  };
  debugLog.step = "5_outputJsonPortion_created";

  const finalOutputItem = {
    json: {
      script_debug_log: debugLog,
      actual_json_output: outputJsonPortion
    },
    binary: { // This is what should be outputted
      binaryFileContent: binaryDataForOutputFile
    }
  };
  debugLog.step = "6_finalOutputItem_constructed";
  debugLog.finalOutputItemKeys = Object.keys(finalOutputItem);
  if(finalOutputItem.binary) {
    debugLog.finalOutputItemBinaryKeys = Object.keys(finalOutputItem.binary);
    if(finalOutputItem.binary.binaryFileContent) {
       debugLog.finalOutputItemBinaryFileContentKeys = Object.keys(finalOutputItem.binary.binaryFileContent);
       debugLog.finalOutputItemBinaryFileContentDataType = typeof finalOutputItem.binary.binaryFileContent.data;
    }
  }

  finalOutputItem.json.script_debug_log = debugLog;
  return finalOutputItem;

} catch (e) {
  debugLog.step = "99_outer_catch_error";
  debugLog.outer_error_message = e.message;
  debugLog.outer_error_stack = e.stack ? e.stack.substring(0, 300) : "no stack";
  return { json: { error: "Outer catch in Convert node.", debug: debugLog } };
}`

(The last UI output for this debugging script showed finalOutputItemKeys: ["json", "binary"] etc. correctly in the script_debug_log that was outputted, but the actual node output was still missing the top-level binary sibling to the json property).

Questions for the Community:

  1. Is this a known issue/bug in n8n v1.94.1 where a Code node might drop a top-level binary property from its returned object when a json property is also present (especially in “Run Once for Each Item” mode)?
  2. Why would the $helpers object be undefined in Code nodes in v1.94.1? Is there a new way to access prepareBinaryData or other helpers?
  3. Are there specific Docker configurations or n8n environment variables that could cause console.log (and error/warn) from Code nodes to not appear in docker logs stdout/stderr? My Docker logs only show n8n system-level messages.
  4. Given the above, what are the most reliable methods in n8n v1.94.1 for a Code node to: a. Generate binary data from incoming JSON. b. Output both some processed JSON and this binary data so that a subsequent “ReadWriteFile” node can access the binary data by its name?

Any insights or further troubleshooting steps would be greatly appreciated. This is blocking a critical archiving step in my workflow.

I don’t see here the correct method for the binary data extraction:
await this.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName);
see Get the binary data buffer | n8n Docs

Actually console.log in the code node is intended for the browser, not for the docker. Console.warn/debug/error is not even implemented, so it has no effect.

The best method is to use the Convert to File node :slight_smile:

1 Like

Thank you so much for your reply. Your advice was incredibly helpful and has clarified several critical issues we were facing with our n8n v1.94.1 setup.

Specifically, these points were major breakthroughs for us:

  1. console.log Behavior: Your explanation that console.log from within a Code node is not intended for Docker logs (but for the browser/UI) is a huge clarification. We were spending a lot of time trying to capture those logs and can now stop chasing that and use other debugging methods.
  2. Using the “Convert to File” Node: Your suggestion to use the built-in “Convert to File” node instead of wrestling with a custom Code node to create binary data is the perfect solution. It’s a much cleaner, more direct, and more reliable “n8n-idiomatic” way to achieve our goal.

Based on your advice, we’re refactoring our workflow to use the “Convert to File” node. This should resolve the primary blocker with our Archive RawWebhookData step. We’ll also take the console.log behavior into account for all future debugging.

Thank you again for taking the time to provide such a clear and effective solution.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.