Help centre / Workflows and automation

HubSpot custom coded workflow action failing: secrets, timeouts, outputs and rate limits

Why HubSpot custom coded workflow actions fail, and how to fix secrets, timeouts, rate limits and data outputs.

By Abdur Rahim Mostafa, HubSpot consultant · Updated 26 October 2026 · 5 min read

Four things commonly make a HubSpot custom code action fail. The code can't authenticate because a secret is missing or holds an old token, it runs past the 20-second limit, it hits an API rate limit, or the outputs it returns don't match what the action defines.

The first thing to check is the workflow's action log for a failed record. Then open the action and run Test action on a similar record. The test shows the status, the data outputs and a log with the memory used and the runtime, which usually points at the problem. Be careful, because a test runs your code for real, and any changes it makes apply to the record you test with.

Why a custom code action fails

The account doesn't have the right plan

As of October 2026, the Custom code action needs Data Hub Professional or Enterprise, according to HubSpot's list of workflow actions. Data Hub used to be called Operations Hub. If the action doesn't appear in the workflow editor, check the subscription first. Custom code runs JavaScript on Node.js, and Python is in beta.

The secret is missing or holds the wrong token

Secrets hold values such as a private app access token, and the code reads them as environment variables, for example process.env.SECRET_NAME in Node.js. You choose the secrets for each action with Add secret, so a secret that exists in the account still has to be selected on the action that uses it. The token behind it needs scopes for every object the code reads or writes. When someone rotates that token, the secret keeps the old value until you update it, and the action's API calls start failing once the old token expires. All the secret values on one action together can't be longer than 1,000 characters. For 401 and 403 responses, read private app token errors.

The code runs too long or uses too much memory

HubSpot's custom code actions guide gives each run 20 seconds and 128 MB of memory, and going over either causes an error. Slow external APIs, loops that fetch associated records one by one and large responses are the usual reasons. You can add up to 50 properties to the action as inputs, which the code reads without an API call, so only fetch what isn't already on the record.

The action hits API rate limits

Calls from custom code count toward the account's HubSpot API rate limits, and a workflow that enrolls thousands of records runs the code thousands of times. If a call fails with a rate limit error, or a 429 or 5XX error from axios or @hubspot/api-client, HubSpot retries the action for up to three days. The first retry comes one minute after the failure, and later gaps grow to a maximum of eight hours. That only happens if the error reaches HubSpot. In Node.js, throw it again in the catch block, and in Python, raise it in the except block. If your code catches the error and carries on, HubSpot has nothing to retry.

You can also slow the action down. Open Configure rate limit in the action, turn on rate limiting and set how many executions run per second, minute or hour. A paused run then logs a message saying when it will resume, and the actions after it wait as well.

The outputs don't match the action

Each output has to be declared under Data outputs with a type, and the code returns it inside outputFields. When you test, HubSpot flags any output the code returned that isn't declared, and later actions can't use it until you add it. String outputs are capped at 65,000 characters, and a longer value fails with OUTPUT_VALUES_TOO_LARGE. To set a datetime property, return a Unix timestamp in milliseconds. For a date property, use the same format with the time set to midnight UTC. If you copy an output into a property with Edit records, check that the two types are compatible.

Code that passes the test and still misbehaves

Variables declared outside exports.main in Node.js, or outside def main in Python, can be reused by later executions, so keep anything specific to one record inside the main function. In Node.js, Math.random can give the same numbers to executions that start together, and HubSpot points to the random-number-csprng library instead. If you write Python, the code field won't show lint errors. From January 5, 2027 you can't create or update actions that use Python 3.9. Existing ones keep running, and HubSpot recommends moving them to Python 3.14.

How to fix a failing custom code action

  1. Find the failed records in the action log or in Review automation issues, as described in workflow action errors.
  2. Set up a test record that looks like one of the failed records, so the test doesn't change live data.
  3. Run Test action and read the status, the outputs and the log, including runtime and memory.
  4. If the log shows a 401 or 403, fix the secret, the token or its scopes.
  5. If it timed out, pass properties in as inputs and make fewer API calls.
  6. Rethrow 429 and 5XX errors so HubSpot can retry them, and turn on the action's rate limit before large enrollments.
  7. Declare every output with the right type, then save.
  8. Put the failed records through again. If the workflow has steps you don't want repeated, a small one-off workflow with only this action is safer than re-enrolling.

How to stop it happening again

Log the record ID and the error message from inside the code, because those logs show up in the workflow's action logs. Name each secret after the app its token comes from, and update it on the day you rotate that token. Check the action log after any large import or list enrollment, since that runs the code many times at once. Keep a copy of the code in version control outside HubSpot, so you can see what changed when an action that worked last month starts failing.

From client work

Custom code isn't always the answer. At Phoenix Industrial Cleaning the portal had no Operations Hub, so custom code in workflows wasn't available. I built the ServiceTrade integration on standard workflows and a lean Zapier setup with the filters first, so routine job edits use zero Zapier tasks.

If your custom code actions keep failing, or nobody on the team knows what they do anymore, I can audit and fix them.

Questions

Does testing a custom code action change my data?

Yes. The test runs the code against the record you pick, and any changes apply to that record. Use a record you keep for testing.

How long does HubSpot keep retrying a custom code action?

Up to three days for a rate limit error, or a 429 or 5XX error from axios or @hubspot/api-client, as long as your code throws the error again. Retries start one minute after the failure, and the gap between attempts grows to at most eight hours.

Which libraries can my code use?

HubSpot lists the libraries available in each language. For Node.js they include @hubspot/api-client, axios and lodash, and for Python they include requests and redis.

Did this fix it?

Written by Abdur Rahim Mostafa. I'm an independent HubSpot consultant with 12 years of HubSpot work. I fix and build HubSpot portals, integrations and automation for teams in the US, UK and Australia. See my case studies or find me on LinkedIn.

Can't find your fix?

Book a free 30-minute call and show me what's happening in your portal. If it needs work, you get a written scope and one fixed price.

Book a free 30-minute call