The InstallIntegration component has two internal code paths that both call createInstallation:
The Configure step inline save (vF component) — fires when the user saves object configuration
The Review step create button (Rk component) — fires when the user clicks "Create Installation"
When the user saves in the Configure step, the first POST /installations succeeds (201) and onInstallSuccess fires. However, if the user proceeds to the Review step and clicks "Create Installation", a second POST /installations fires and returns 409 (or 500 "duplicated key not allowed") because the installation was already created.
The createInstallation guard in the Pp hook checks if (o) where o is the installation from useInstallation() (Tn()). After the first create succeeds, setInstallation(P) updates the React Query cache via setQueryData. But the Review step's onCreate handler is memoized with useCallback and its closure captures a stale o = undefined from before the first create — so the guard passes and the duplicate POST fires.
Additionally, the component exposes no onError callback on InstallIntegrationProps, so consumers cannot suppress the 409 error UI that the widget renders inline via setSubmissionError.
To reproduce
Open the InstallIntegration dialog for an OAuth provider (e.g., Asana)
Complete the OAuth flow
In the Configure step, save object configuration (first POST fires, returns 201)
Proceed to the Review step and click "Create Installation" (second POST fires, returns 409)
The widget displays the 409 error inline
Expected behaviour
Only one createInstallation POST should fire per session. After the first create succeeds, the Review step should either skip the create or the Pp guard should re-read the current installation value from the query cache instead of using a stale closure.
Alternatively, an onError callback on InstallIntegrationProps would allow consumers to handle the 409 gracefully.
Environment
@amp-labs/react v2.15.1
The InstallIntegration component has two internal code paths that both call createInstallation:
The Configure step inline save (vF component) — fires when the user saves object configuration
The Review step create button (Rk component) — fires when the user clicks "Create Installation"
When the user saves in the Configure step, the first POST /installations succeeds (201) and onInstallSuccess fires. However, if the user proceeds to the Review step and clicks "Create Installation", a second POST /installations fires and returns 409 (or 500 "duplicated key not allowed") because the installation was already created.
The createInstallation guard in the Pp hook checks if (o) where o is the installation from useInstallation() (Tn()). After the first create succeeds, setInstallation(P) updates the React Query cache via setQueryData. But the Review step's onCreate handler is memoized with useCallback and its closure captures a stale o = undefined from before the first create — so the guard passes and the duplicate POST fires.
Additionally, the component exposes no onError callback on InstallIntegrationProps, so consumers cannot suppress the 409 error UI that the widget renders inline via setSubmissionError.
To reproduce
Open the InstallIntegration dialog for an OAuth provider (e.g., Asana)
Complete the OAuth flow
In the Configure step, save object configuration (first POST fires, returns 201)
Proceed to the Review step and click "Create Installation" (second POST fires, returns 409)
The widget displays the 409 error inline
Expected behaviour
Only one createInstallation POST should fire per session. After the first create succeeds, the Review step should either skip the create or the Pp guard should re-read the current installation value from the query cache instead of using a stale closure.
Alternatively, an onError callback on InstallIntegrationProps would allow consumers to handle the 409 gracefully.
Environment
@amp-labs/react v2.15.1