Why is my Zoho Deluge function not working?
Deluge failures come in two flavours: functions that error every time and functions that work for most records but fail on a few. The second kind causes the most grief. The script is fine right up until it meets a record shaped slightly differently from the one it was tested against.
Here is the order we work through when a client reports a broken function:
- Read the failure notification email. Zoho sends one to the function’s author every time a function errors at runtime.
- Run the function manually against a record you know it failed on.
- Hunt for nulls. Blank fields cause most intermittent failures.
- Check datatypes, especially anything pulled out of a JSON response.
- Confirm the trigger context. Workflow, button and schedule executions behave differently.
- Check the connection the function uses and its OAuth scopes.
- Check the limits: API call caps and execution time.
Most problems surface in the first three steps. The rest of this guide takes each one in turn.
How do I read Deluge function logs?
In Zoho CRM, go to Setup → Developer Space → Functions. Every runtime failure generates an email notification to the user who created the function. That detail matters more than it sounds: if the function was written by a developer or an employee who has since left, those notifications are landing in an inbox nobody reads. Sort out ownership of the function before you do anything else.
In Zoho Creator, open the application in edit mode and check the Logs section, which records executions along with anything the script printed using info statements.
Two habits make debugging far less painful:
- Run the function manually. Open it in the editor, execute it with a real record ID and read the error it returns directly.
- Add info statements at every decision point. “Reached line 40, items count = 3” tells you more than anything Zoho will volunteer. Zoho’s runtime errors are genuinely unhelpful at times - “Internal error occurred” doesn’t even tell you which line died.
Cause 1: the script assumes a field has a value
The most common Deluge failure of all is a script reading a field that happens to be blank. The function was tested against a nicely filled-in record, deployed, then fed a record where the field is empty. Anything downstream of that read - a comparison, a calculation, a .get() on the missing value - falls over.
The fix is ifnull(), which substitutes a default when a value is missing. Here is a defensive version of a pattern we see broken constantly:
// Invoked from a workflow on Deals
resp = invokeurl
[
url : "https://api.example.com/v1/orders/" + dealId
type : GET
connection : "example_api"
];
// getJSON hands back text, even when the value looks numeric
amount = ifnull(resp.getJSON("amount"),"0").toDecimal();
items = resp.getJSON("items");
if(items != null && items.size() > 0)
{
for each item in items
{
info "Processing SKU: " + item.get("sku");
}
}
else
{
info "No items returned for deal " + dealId;
}
Three things in that snippet are doing protective work. ifnull() guards the amount. The null-and-size check guards the loop. The info statements leave a trail you can follow when something still goes wrong.
Fragile scripts without those guards are one of the most common things we rebuild during Zoho CRM projects - functions written years ago that fall over the moment a field is blank.
Cause 2: datatype mismatches, especially from getJSON
Deluge is loosely typed and that flexibility bites. The classic case: a value extracted from a JSON response with getJSON() arrives as text even though it looks like a number. Compare it against a numeric field and the comparison fails silently. No error, just an if branch that never runs.
Convert explicitly before comparing or calculating:
- toDecimal() or toLong() for numbers
- toString() when you do need text
- toDate() for date strings, with the source format specified
The same problem appears in reverse when concatenating: adding a number to a string can throw at runtime depending on the order of operands. When a function behaves inconsistently rather than failing outright, type coercion should be your first suspect after nulls.
Cause 3: map and list confusion
Deluge has maps (key-value pairs) and lists (ordered collections) and scripts regularly treat one as the other. The symptom is usually an error about a method that cannot be applied, or simply nothing happening.
The trap worth knowing about: some API responses change shape depending on how many results come back. One matching record can arrive as a single map while several arrive as a list of maps. A script written against the single-record case dies the first time a search returns two results. If a function passes testing then fails in production at random intervals, check whether the data it receives always has the structure the code assumes. Test with .size() before indexing, or normalise single results into a list before looping.
Cause 4: API calls inside the function are hitting limits
Every zoho.crm.getRecordById(), zoho.crm.updateRecord() or invokeurl call inside a function consumes API credits and Deluge caps how many integration calls a single execution can make. A function that loops through a few thousand records calling the API once per row will exhaust something - the per-execution cap, the daily allowance or the execution window, whichever comes first.
The pattern to avoid is the call-inside-a-loop. Fetch records in bulk, process them in memory, write back in batches. If your organisation is already brushing against its daily ceiling, our guide to Zoho CRM API limits covers how to find what’s burning credits and what to do about it.
Cause 5: the trigger context is not what the script expects
The same function can be attached to a workflow, a button or a schedule and each context feeds it differently:
- Workflows pass arguments mapped from the triggering record. If the mapping points at a field that is blank, the function receives an empty value and you’re back at cause 1.
- Buttons run when a person clicks them, which means a specific record and a specific user. A function that edits a restricted field can work for the admin who built it and fail for a user on a tighter profile.
- Schedules run with no triggering record at all. Any line expecting a record ID as input gets nothing.
This is why “it works when I run it manually” proves very little. A manual run uses your inputs and your permissions. Recreate the failing context exactly: same trigger, same record, same user where possible.
One related check before you blame the script: confirm the automation around it is actually firing. A workflow whose criteria never match looks identical to a broken function. Our guide to Zoho CRM workflows not triggering covers that side of the problem.
Cause 6: the connection is missing scopes
Functions that call Zoho or third-party APIs through a named connection fail when that connection lacks the OAuth scopes the call needs. The giveaway is an error mentioning a scope mismatch or a 401, though sometimes you just get an empty response back.
Check Setup → Developer Space → Connections in CRM. Verify two things:
- The connection includes every scope the function’s calls require. Adding a new update call to a function whose connection only carries read scopes will fail until the connection is recreated with write access.
- The person who authorised the connection still has an active account. Connections authorised by a deactivated user stop working even though nothing in the function itself has changed.
Re-authorising after a scope change isn’t optional. Adding scopes to the definition does nothing until someone clicks through the authorisation flow again.
Cause 7: you’re hitting execution limits
Deluge gives each execution a hard window. Synchronous contexts are the tightest: a function behind a button click gets cut off after roughly ten seconds, because a user is visibly waiting for the answer. Long loops, row-by-row API calls and large search results are the usual culprits.
If a function dies partway through with no logic error anywhere, time is the likely killer. Options, in rough order of preference:
- Reduce the work: fetch in bulk, filter before looping, exit early when there’s nothing to do.
- Move the heavy processing onto a schedule, which gets a more generous window and runs without anyone waiting on it.
- Accept that the job has outgrown a function. If it needs minutes of processing and its own data structures, it belongs in a purpose-built Zoho Creator application.
Quick diagnostic checklist
- Found the failure notification email? Confirm who receives it, then read the latest one.
- Run the function manually against a failing record. Same error?
- Any field the script reads that could be blank? Guard it with ifnull().
- Any value from getJSON() compared or calculated without an explicit type conversion?
- Does the data always have the shape the code assumes - map vs list, single result vs many?
- Any API call inside a loop? Count how many calls a single execution makes.
- Does the trigger context match your test conditions - workflow argument mapping, button user, schedule with no record?
- Connection scopes checked and the connection re-authorised since they last changed?
- Could the function simply be running out of time mid-execution?
When to stop debugging and get help
A null guard or a type conversion is a ten-minute fix once you’ve found it. A function that fails intermittently across thousands of records, calls three external services and was written by someone who left two years ago is a different job entirely. This is the point where most people should stop and get help, because every speculative edit to a live function carries real risk.
That’s work we do daily. Hire a Zoho developer for a proper diagnosis and rebuild, with a developer assigned within 24 hours. If the broken function is blocking your business right now, our emergency Zoho developer service is the faster route: a senior developer responds within 30 minutes during UK business hours. Either way, get in touch to book a free discovery consultation and we’ll tell you whether the script needs a patch or a rewrite.