Google Sheets - Row Update Trigger (Test Input/output)

Hi all — quick question about the Google Sheets Trigger (specifically Updated Rows).

I’ve noticed the output structure differs between manual “Test/Execute” runs and an activated production workflow. In test mode, the trigger returns data in a way that doesn’t match the “published” runtime output, so expressions like:

  • {{ $json.previous["Status"] }}

  • {{ $json.current["Status"] }}

don’t resolve during testing (because previous / current aren’t present in the same shape in my JSON).

Is there any recommended way to test with the same input structure as production?
For example:

  • a way to run a test execution that produces the real previous/current payload, or

  • a best practice for simulating production trigger output so downstream nodes can be tested reliably.

Thanks!

Hi @OllieC

Welcome to the n8n community :tada:

this isn’t a bug, it’s expected behavior from the Google Sheets Trigger in n8n, and it catches a lot of people the first time.

Why this happens

In n8n, manual executions (Execute workflow / Execute node) don’t behave the same way as live (“production”) executions for trigger nodes.

When you run the Google Sheets Trigger manually, n8n doesn’t receive a real event from Google. Instead, it returns a sample / partial payload, which often doesn’t match the structure of a real update event. This is documented as expected behavior for Google triggers, including Google Sheets.

In contrast, when the workflow is activated, the trigger runs via Google’s push mechanism and n8n can:

  • Keep internal state
  • Compare changes
  • Emit the real previous / current objects

That’s why expressions like:

{{ $json.previous["Status"] }}
{{ $json.current["Status"] }}

won’t resolve during manual tests, but work fine once the workflow is active.

There isn’t a supported setting or “test mode” that forces the Google Sheets Trigger to emit the exact production payload during a manual run.

Recommended (documented) ways to test reliably
  1. Test the trigger in active mode (only way to get the real payload)

Activate the workflow, update an existing row in the sheet, and inspect the execution in Executions.
This is the only mode where previous / current are guaranteed to be present.

Once you have a good execution, you can:

  • Open it in the editor
  • Use Debug / Copy to editor to continue building downstream logic with the real data
  1. Pin real trigger data (closest thing to “simulate production”)

After capturing a real execution:

  • Open it in the editor
  • Pin the trigger output

From that point on, manual executions will reuse the pinned data instead of calling the trigger again, so all downstream nodes see the same previous / current structure every time.

This is the officially documented way to work with stable trigger data during development.

  1. Optional: mock with a Set node

A common community workaround is to copy the real previous / current JSON from a production execution into a Set node and build/test everything downstream against that.
This pairs well with data pinning and avoids re-triggering Google while iterating.

TL;DR
  • The mismatch between manual and live trigger output is expected and documented
  • There’s no way to force the Google Sheets Trigger to emit production-style previous/current data in manual tests
  • The supported workflow is:
  1. Activate once
  2. Capture a real execution
  3. Load it into the editor and/or pin the data
  4. Build and test downstream nodes against that
2 Likes

Cool - thanks Tamy - appreciate the quick follow up :wink:

1 Like

Happy to help!

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