fix(ui): stop New Agent infinite render loop in AgentConfigForm

Creating an agent rendered a blank page (now a "Maximum update depth
exceeded" error card). `triggerTestEnvironment` was rebuilt every render
because `runEnvironmentTest` depends on the `useMutation` result object,
which gets a fresh identity each render. The `onTestActionChange` effect
then fired every render and pushed a new function into the parent's
state (setTestAgentAction), forcing another render — an infinite loop.

Hold the latest trigger behavior in a ref and hand the parent a stable
callback so the effect runs once. The Test Agent button still invokes the
current logic via the ref.
This commit is contained in:
Devin Foley committed 2026-06-19 09:43:21 -07:00
1 parent b600e18626
commit 7362ecda02
1 file changed
+14 -3
+14 -3
View File
@@ -550,10 +550,21 @@ export function AgentConfigForm(props: AgentConfigFormProps) {
setTestActionPending(false);
}
}, [selectedCompanyId, isCreate, isDirty, handleSave, testEnvironment]);
const triggerTestEnvironment = useCallback(() => {
if (testEnvironmentDisabled) return;
void runEnvironmentTest().catch(() => undefined);
// `runEnvironmentTest` (and `testEnvironmentDisabled`) change identity on every
// render because `useMutation` returns a fresh result object each time. Hold the
// latest behavior in a ref so the trigger handed to the parent stays referentially
// stable — otherwise the `onTestActionChange` effect below re-runs every render,
// pushing a new function into parent state and causing an infinite update loop.
const triggerRef = useRef<() => void>(() => {});
useEffect(() => {
triggerRef.current = () => {
if (testEnvironmentDisabled) return;
void runEnvironmentTest().catch(() => undefined);
};
}, [runEnvironmentTest, testEnvironmentDisabled]);
const triggerTestEnvironment = useCallback(() => {
triggerRef.current();
}, []);
useEffect(() => {
if (!showAdapterTestEnvironmentButton || !props.onTestActionChange) return;