Environment:
- Forge app, Custom UI,
jira:uiModificationsmodule - Site: arzenicstech.atlassian.net (Jira Cloud)
- Development environment (Forge dev mode)
- Node.js runtime: nodejs24.x
What I’m trying to do:
I’m building a jira:uiModifications app to dynamically filter a “child” field’s options (customfield_11207, a native Select List single-choice field) based on a “parent” field’s value (customfield_11206, also native Select List) — live, on the Global Issue Create screen.
Setup:
- Manifest declares the module correctly:
yaml
jira:uiModifications:
- key: dd-live-uim
title: Dynamic Dependent Live Options
resource: dd-uim-ui
resolver:
function: uimResolver
- A UI modification entity was successfully created via
POST /rest/api/3/uiModifications(usingapi.asApp()— note:api.asUser()fails with 403 “Only apps can access this resource (impersonated requests are not allowed)”, which isn’t clearly called out in the docs for this specific endpoint):
json
{
"name": "Parent-Child Category Live Test",
"contexts": [{ "projectId": "10232", "issueTypeId": null, "viewType": "GIC" }],
"data": "{\"parentFieldId\":\"customfield_11206\",\"childFieldId\":\"customfield_11207\",\"mapping\":{...}}"
}
Response: 201, entity ID returned successfully.
- Client code registers both fields and calls
setOptionsVisibilityon change:
jsx
uiModificationsApi.onChange(async ({ api, change, uiModifications }) => {
const { current } = change;
const changedFieldId = current.getId();
for (const um of (uiModifications || [])) {
const cfg = JSON.parse(um.data);
if (changedFieldId !== cfg.parentFieldId) continue;
const parentOptionId = current.getValue()?.id ?? null;
const allowedChildOptionIds = cfg.mapping?.[parentOptionId] || [];
const childField = api.getFieldById(cfg.childFieldId);
if (childField) childField.setOptionsVisibility(allowedChildOptionIds, true);
}
}, ({ uiModifications }) => {
// returns both parentFieldId and childFieldId for registration
});
What I observed:
- On the first real test, the mechanism partially worked: selecting the parent’s second value correctly filtered the child’s options. Selecting the parent’s first value did not filter correctly (both options remained visible).
- After adding debug logging (both
console.login the browser console andinvoke()calls to a backend resolver, verified deployed viaforge logsand browser DevTools source search), neither produces any output — not even fromonInit, which per the docs should fire unconditionally on mount. - I confirmed the debug code is present in the deployed bundle (verified via
grepon the built JS and via DevTools “Search across files”). - I have been unable to locate the correct iframe context in DevTools to inspect
console.logoutput directly (the UIM app’s iframe does not appear distinguishable among the many iframes Jira’s Global Issue Create screen loads).
Question:
- Is there a reliable, documented way to access the browser console output specifically for a
jira:uiModificationsCustom UI resource on the Global Issue Create screen (given the large number of unrelated iframes GIC loads)? - Is there a known issue with
onChange/onInitcallbacks silently failing to execute (or being torn down before async work likeinvoke()completes) on GIC specifically, as opposed toIssueView? - Are there known constraints around calling
setOptionsVisibilityinconsistently on first-selection vs subsequent selections? - Is
onErrorreliably able to surface silent conflicts (e.g.,MULTIPLE_APPS_CONFLICT,APPLY_CHANGES_FOR_UNREGISTERED_FIELD) in this scenario, and is there a recommended debugging workflow for UIM apps beyondforge logsand browser console?
Any pointers to a working, minimal reproduction of onChange + setOptionsVisibility on GIC would be appreciated — happy to share the full manifest/code if useful.