Skip to main content

Troubleshoot Functions

Work from the symptom you can see. Most failures fall into one of three places: the code was rejected when you saved it, the execution failed when it ran, or the execution never happened at all.

Start with three checks​

  1. Is the function active? Execute matches active functions only, so an inactive function returns 404 exactly like a missing one.
  2. Did a run happen? Every execution creates an invocation record. No record means the function never started.
  3. Which version ran? Records store the version that executed. A function that behaves unexpectedly may be running code you have since changed.

A function will not save​

MessageWhat it meansFix
Code must define main(params, user_data, sdk_client)Validation searches for that literal text. It is a string match, not a parse, so annotations, renamed parameters, or different spacing fail even when the function is valid PythonCopy the signature line exactly, and rename parameters inside the body if you prefer
Code compilation failedThe source is not valid Python, or uses a language feature the sandbox does not allowRead the named error. If the syntax is valid Python, rewrite the construct using simpler statements
webhook_url is required for PROXY modeA proxy function was saved without a destinationSupply a URL with a scheme and host
Code is required for APP mode functionsAn app function was saved with no codeAdd code, or change the execution mode
Invalid CEL syntaxA filter condition could not be parsedCorrect the expression. See Filter conditions

A function saves but fails to run​

MessageWhat it meansFix
ImportError, listing allowed modulesThe code imported a module outside the sandbox allowlist. Imports are checked when they run, so an import inside a branch fails only when that branch executesUse a permitted module, or move the work to a proxy function
main must define a functionmain exists but is not callable, or was set to NoneDefine main as a function at the top level of the module
main() accepts N parameters but must accept exactly 3The runtime signature check found the wrong arityTake exactly params, user_data, and sdk_client
A NoneType attribute or call error naming the SDKA method was called on the wrong SDK attributeCheck the client path, such as sdk_client.database rather than a misspelling
The execution timed outSynchronous work exceeded the execution wait, 900 seconds by defaultExecute asynchronously and collect the result by task id

Results are not what you expect​

SymptomWhyWhat to do
An update returned 200 but nothing changedVersions are created only when a versioned field actually changes. A request matching the stored values returns a success status with an error body reading No changes detected, version unchangedConfirm the field and value differ. Read the body rather than the status code
Reverting restored the code but not the configurationRevert restores code and filter_conditions only. Other versioned fields keep their current valuesRead the history and set the remaining fields explicitly after reverting
The version number went up after a revertRestoring code is itself a change, so the counter advances rather than rewindingExpected behavior. History is append-only
The output does not match the source you are readingThe run used an earlier versionRead the single invocation through the function-scoped endpoint, which returns the code that actually ran
A proxy function reports success for a failed callA non-2xx webhook response is returned rather than raisedCheck status_code rather than assuming a result means success
The log ends mid-runA limit was reached: 2,000 entries, 1 MiB total, or 10,000 characters in one messageLog decisions and failures rather than every iteration

A run never happened​

An event-triggered function that produces no invocation record at all was skipped by its filter conditions. A skipped execution dispatches no task and creates no record, so nothing marks the attempt.

A condition that errors counts as not matching. An expression that references a field the event doesn't carry, divides by zero, or uses an invalid regular expression resolves to false and skips the function without an error.

Check the expression against the event's actual parameters. An absent or empty expression permits execution, so a function that stopped running usually gained a condition rather than losing one. Filter conditions apply to event triggers only: if the function runs when called directly but not from an event, the condition is the cause.

Access is refused​

A 403 has two causes. The function is not public and the request carried no credentials, or policy denied an authenticated caller.

Send credentials first. If you are already authenticated, confirm your permission to execute that function. Do not set is_public to work around a permission problem — it makes the function executable by anyone, with no policy check at all. See Security and limits.

A 404 from execute means the app slug is wrong, the function slug is wrong, or the function is inactive. Slugs are generated from the name and may carry a numeric suffix when another function claimed the same one.

Functions are unavailable for the site​

Executions are rejected without retry when the organization's account is not active. The task is refused rather than queued, so no result appears.

Check the organization's billing state before investigating the function itself.

Prepare a support request​

Capture these, and confirm none carries a secret before sharing:

  • The app slug and function slug.
  • The celery_task_id of a failing run.
  • The invocation record, including its status and captured logs.
  • The version that ran, from the record's history id.
  • Whether the same call succeeds synchronously and fails asynchronously, or the reverse.