initialNodes mutates the graph payload it is given
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
Research direction
Start in packages/rad-components/src/components/appgraph/AppGraph.tsx, focusing on initialNodes and the Inbound gateway-direction workaround. Read and run packages/rad-components/src/test/graphInvariants.test.ts to confirm the input graph remains unchanged across repeated use; done means the correction still occurs without mutating the caller's payload.
Written by the indexing model from the issue text.
Description
Steps to reproduce
- Render an application graph containing an
Applications.Core/gatewaysresource reached by a connection markedInbound. - Render the same graph payload object a second time without re-fetching it.
Observed behavior
initialNodes in packages/rad-components/src/components/appgraph/AppGraph.tsx writes to the data it was given:
if (
connection.direction === 'Inbound' &&
parsedConnection.type === 'Applications.Core/gateways'
) {
connection.direction = 'Outbound';
}
The caller's graph object is modified in place. The second render therefore sees different input from the first, because the first render already rewrote it. The function is not idempotent with respect to its argument.
This is currently masked because the graph is re-fetched on each mount, so in practice the object is usually fresh. It stops being masked as soon as the payload is cached, memoized, held in state, passed to two components, or reused in a test — all of which are likely during the graph rearchitecture.
The comment above the block (We have a bug where the connections have the wrong direction) indicates this is a deliberate workaround for upstream data, so the correction itself may be intended. The in-place write is the part that is not.
Desired behavior
initialNodes should treat its argument as read-only and derive the corrected direction locally, rather than mutating the caller's object. A pure function of the graph payload is also a precondition for memoizing the layout, which is worth doing independently.
Workaround
Callers must pass a fresh copy of the graph payload on every render. Tests must deep-clone shared fixtures per use, which is what the new invariant suite does.
Additional context
Pinned by GU-05b in packages/rad-components/src/__test__/graphInvariants.test.ts, added in nicolejms/dashboard#1, tagged KNOWN-DEFECT.
Found while building the graph invariant suite ahead of the graph rearchitecture, tracked in docs/design/2026-09-dashboard-plugin-test-plan.md.
- Dominant language
- TypeScript
- Stars
- 18
- Forks
- 13
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 10
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from radius-project/dashboard
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
radius-project/dashboard#373 ·
-
bug triaged
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
radius-project/dashboard#370 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
radius-project/dashboard#366 · 5 comments ·
-
triaged
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
radius-project/dashboard#365 ·
-
triaged
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
radius-project/dashboard#364 ·
All issues in radius-project/dashboard
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100