Tips > Reliability & Performance

Add Console Logging with a Code Node to Inspect Data

When the output panel does not show enough detail, or you need to inspect a specific nested property, insert a temporary Code node that logs the full data st...

TipIntermediate2 min read

When the output panel does not show enough detail, or you need to inspect a specific nested property, insert a temporary Code node that logs the full data structure. This is especially useful for debugging expression errors where you are not sure what properties exist on the incoming data.

Real-world example: An HTTP Request node returns a deeply nested JSON response and your expression {{ $json.data.results[0].metadata.tags }} returns undefined. You need to see the actual structure.

// Place this Code node between the HTTP Request node
// and the node that uses the expression.

// Log the complete structure of every incoming item
for (const item of $input.all()) {
  console.log(
    "=== ITEM DATA ===\n" +
    JSON.stringify(item.json, null, 2)
  );
}

// Pass all items through unchanged
return $input.all();
```text
The `console.log` output goes to the **server's stdout** (visible in Docker logs via `docker logs n8n`), not the browser UI. However, the Code node's output panel shows the returned items, so the debug technique works by passing data through. The structured log reveals the actual data shape:

```json title="Console Output Reveals the Real Structure"
{
  "data": {
    "results": [
      {
        "meta": {
          "tags": ["urgent", "billing"]
        }
      }
    ]
  }
}
```text
> **Tip: The Fix**
>
> The property is `meta.tags`, not `metadata.tags`. The correct expression is `{{ $json.data.results[0].meta.tags }}`. Without the debug log, you would be guessing at property names from the API documentation, which often differs from the actual response.

This technique takes 30 seconds to set up and immediately reveals the exact data structure. Remove the debug Code node after fixing the issue.

**Related:** [Always Set an Error Workflow on Every Production Workflow](../error-handling-and-reliability/01-always-set-an-error-workflow-on-every-production-workflow.md) | [Break Large Workflows into Sub-Workflows](../workflow-architecture/01-break-large-workflows-into-sub-workflows.md)

Want this running in your stack?

I build production n8n and Cloudflare automation for teams — the same engineering behind HarperFlow. Fixed-price, escrow-protected, US-based.