diff --git a/desktop/src-tauri/src/commands/personas/update/concurrent_edit_tests.rs b/desktop/src-tauri/src/commands/personas/update/concurrent_edit_tests.rs index b19821afd8..55af0b4fde 100644 --- a/desktop/src-tauri/src/commands/personas/update/concurrent_edit_tests.rs +++ b/desktop/src-tauri/src/commands/personas/update/concurrent_edit_tests.rs @@ -337,7 +337,7 @@ async fn retain_failure_after_persist_is_returned_not_swallowed() { let result = update_persona_with( update_request("p1", "Alice retain-fail", Some(R1)), app.handle().clone(), - |_app, _state, _persona| { + |_app, _state, _persona| -> Result<(), String> { Err("simulated retain / publish failure after persona persisted".to_string()) }, ) diff --git a/desktop/src/features/agents/ui/AgentEditMergedDialog.tsx b/desktop/src/features/agents/ui/AgentEditMergedDialog.tsx index d0612f5cba..cbe193e5ea 100644 --- a/desktop/src/features/agents/ui/AgentEditMergedDialog.tsx +++ b/desktop/src/features/agents/ui/AgentEditMergedDialog.tsx @@ -558,11 +558,8 @@ export function AgentEditMergedDialog({ !isAvatarUploadPending && displayName.trim().length > 0 && providerValid && - // D-side credential gate: whenever the definition is editable, its required - // credential keys must be satisfied — independent of the instance gate, so a - // linked instance pin can't unblock a definition that main would reject. - // Team-managed definitions (defReadOnly) never block: the user can't change - // their credentials, so their readiness is not this form's concern. + // D-side credential gate: required keys must be satisfied when the definition + // is editable. Team-managed (defReadOnly) never blocks — user can't change them. (!showDef || defReadOnly || !dAdvanced.requiredEnvKeyMissing) && (showInst ? !requiredEnvKeyMissing && @@ -570,9 +567,8 @@ export function AgentEditMergedDialog({ (selectedRuntimeId !== "custom" || inheritHarness || agentCommand.trim().length > 0) && - // Instance name must be non-blank when the name field controls submission - // (no name pool — pool-named instances get their names from the definition - // pool and do not submit the visible name field). + // Block submission when the instance name field controls the name and + // the user has left it blank (no name pool — pool-named instances skip). ((def?.namePool?.length ?? 0) > 0 || instanceName.trim().length > 0) : true);