Loading

Extensions

An extension is a small piece of custom code that the platform runs at a defined point, such as when a field's value is drawn or when a workflow reaches a particular step. Every change is kept as a version, checked automatically, approved and only then put live, so custom logic can be added without editing the platform's own files.

Where to find it

Architect Panel → Automation:

  • Extensions — approve a version, put it live, roll it back, switch it off, and see its runs

Architect Panel → Layout & Pages:

  • App Code — the in-browser editor where extension code is written

Who does what

Writing extension code needs a developer. Running extensions safely does not. An architect, without writing code, can approve a version, put it live, roll back, disable it, clear its circuit breaker and read its run history, all from the Extensions screen. Any administrator can open App Code and write or check code, but only an architect can approve or put a version live.

Hooks: where an extension can run

Each extension is attached to one hook. The Hooks card at the bottom of the Extensions screen lists every hook with what it binds to, its time budget and what it is allowed to do. Two hooks are called by the platform today:

  • field.render: draws one chosen field on a record's form in place of the standard control. If the extension fails or is not live, the standard control is drawn as usual.
  • workflow.node: runs as an Extension step in a workflow built in the Workflow Builder. See Workflow Builder.

The other hooks in the list (record validation and saving, pages, endpoints, tasks) are defined but not yet called anywhere, so an extension written for them never runs. Some hooks also need a separate extension runner; where a system has none, the Hooks card says "no runner - refused on this install".

Binding: what it runs for

An extension runs only for the thing it is bound to. The detail panel shows this as Bound to. App Code does not set the binding, so after creating an extension an architect sets it on the extension's record in the Extensions datastore (Data → Datastores): Bound Datastore and Bound Field for a field, or Bound Key for a workflow step, matching the key the step names.

Statuses

  • draft: being written. gated: the latest version passed the code checker.
  • dryrun: being tested. live: running. Only live extensions ever run.
  • disabled: switched off by a person. quarantined: switched off automatically by the circuit breaker, or because the code checker was updated. See Limits and the Circuit Breaker.

Reading the Extensions screen

  1. The Installed list shows each extension's Name, Key, Hook, Status, Live and Draft versions and Breaker. "no such hook - this can never fire" means it names a hook that does not exist.
  2. Click Open for the detail: hook, Bound to, limits, the status buttons, the Circuit breaker card, Versions and Recent runs.
  3. A banner "Nothing published here can run." means no extension is live.

What goes wrong and how to tell

  • A live extension never seems to run: its hook is one the platform does not call yet, or its binding is empty or wrong. Check Hook and Bound to.
  • A workflow stops with "No live extension is registered for the workflow step": no live extension has a Bound Key matching that step. Bind one and put it live.
  • Status has changed to quarantined: the circuit breaker switched it off. Read the reason on the detail panel.

Worked example

A developer writes an extension in App Code, on the hook field.render, that shows a contract's end date on the contract form together with its remaining term, such as "4 months left". The architect sets its Bound Datastore and Bound Field to the contracts datastore's end-date field, opens it on the Extensions screen, approves the version and clicks Put live. Contract forms now show the remaining term beside the date. When a later version misbehaves, the architect uses Roll back to this on the previous version from the Versions card.

Recommendations

  • Use an extension only when configuration cannot do the job.
  • Check the hook is one the platform calls before commissioning code for it.
  • Set the binding before putting a version live.
  • Keep approving and writing with different people, even though the screen does not enforce it.