Forge Jira Bridge API
Register custom-field UIM handlers
customFieldApi.registerUIMHandlers lets an opted-in Forge object custom field
validate UIM value and option-visibility proposals in its mounted view or edit runtime.
This API requires a Jira host with the completed owner-handler capability enabled.
Older or disabled hosts reject with error.code === 'FCF_UIM_HANDLERS_UNSUPPORTED'.
Use isFcfError(error) before branching on error.code in a catch (error: unknown) block.
import { customFieldApi, isFcfError, type UIMHandlers } from '@forge/jira-bridge';
type Service = { id: string; name: string };
const handlers: UIMHandlers<Service> = {
setValue(proposed, context) {
// Validate the caller and proposed value using your app's domain policy.
// Return a canonical JSON object, or null to clear the field.
return { accepted: true, value: proposed };
}
};
const registration = await customFieldApi.registerUIMHandlers(handlers);
// When this runtime unmounts:
await registration.unregister();
setValue and setOptionsVisibility are independently optional. Register either,
both, or an empty handler map. A registered runtime without the requested handler
does not support that operation: Jira must reject it with FCF_OPERATION_UNSUPPORTED
through UIM's error channel without applying the proposal. A missing registration
still follows the host's readiness rules. Both handlers support synchronous
and asynchronous results: { accepted: true, value } or
{ accepted: false, code, message? }. null clears an object field, undefined,
non-JSON values and malformed results are invalid. Jira validates and applies accepted
results through its existing form or persistence path. Handlers must not persist a
proposal or call view.submit themselves.
The host supplies callerAppId, fieldId, requestId, renderContext,
currentValue and optionsVisibility. These describe the UIM invocation, they do not
provide authenticated app-to-app resolver provenance. UIM setters remain synchronous
and chainable, with application failures delivered through uiModificationsApi.onError.
Registration resolves after the host stores the callable handlers. Register once in
each mounted runtime. Re-registering replaces that runtime's handlers, disposing an
older registration cannot remove its replacement. unregister() returns an idempotent
promise and disables local callbacks immediately, even if host cleanup rejects.
Application cleanup must also dispose a registration that resolves after unmount.
Keep isUIModificationsEnabled: true in the existing jira:customField or
jira:customFieldType module. No extra manifest resource or generic bridge API is
required. Host deployment and controlled app migration must precede general use,
older hosts retain their prior object-UIM behavior.