PrismLibrary/Prism · error · InvalidOperationException
The DialogCloseCallback has not been properly initialized…
Error message
The DialogCloseCallback has not been properly initialized. This must be initialized by the DialogService, and should not be set by user code.
What it means
DialogCloseListener wraps the callback the DialogService injects into a dialog. Invoking it before/without DialogService initialization leaves the internal callback null (default case), so it throws InvalidOperationException explaining the listener must be set by DialogService and not by user code.
Solutions
- Show the dialog via IDialogService.ShowDialogAsync so the listener is injected
- Only call RaiseRequestClose after OnDialogOpened has executed
- Never assign/construct DialogCloseListener yourself
- In tests, set the private callback field via reflection or use the DialogService
Example fix
// before var dialog = new MyDialog(); dialog.RaiseRequestClose(new DialogResult()); // listener not set // after await dialogService.ShowDialogAsync(nameof(MyDialog), parameters, callback);
Defensive patterns
Strategy: try-catch
Validate before calling
// Only close dialogs that went through IDialogService bool canClose = _dialogOpened; // set true in OnDialogOpened if (!canClose) return;
Type guard
bool listenerInitialized(IDialogAware dialog) =>
(bool)(dialog.GetType()
.GetField("_listener", BindingFlags.NonPublic | BindingFlags.Instance)
?.GetValue(dialog) is DialogCloseListener l && l.IsInitialized); Try / catch
try { RaiseRequestClose(new DialogResult()); }
catch (InvalidOperationException ex) { logger.LogError(ex, "Dialog close attempted before initialization"); } Prevention
- Always show dialogs via IDialogService.ShowDialogAsync
- Never call RaiseRequestClose before OnDialogOpened
- Never construct or assign DialogCloseListener manually
- Guard RaiseRequestClose calls with an OnDialogOpened-completed flag
When it happens
Trigger: Calling RaiseRequestClose / DialogCloseListener.Invoke from a dialog view-model whose listener was never injected, e.g. constructing the dialog manually with new instead of through IDialogService, or closing before OnDialogOpened runs.
Common situations: Manually instantiated dialogs in unit tests; calling RaiseRequestClose inside constructors or before the dialog is shown; copying dialog code without the DialogService pipeline.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot change the region name once is set. The current…
- Layout 's Children property is not empty. This control is…
- Navigation cannot proceed until a region is set for the…
- ScrollView's Content property is not empty. This…
- The host has not yet been created. The Shell must first be…
AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15).
Data as JSON: /api/errors/d0e3d63be9292ef8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Prism.Core/Dialogs/DialogCloseListener.cs:72
Result = result
});
/// <summary>
/// Invokes the initialized delegate with the specified <see cref="IDialogResult"/>
/// </summary>
/// <param name="result"></param>
public async void Invoke(IDialogResult result)
{
switch(_callback)
{
case Action<IDialogResult> actionCallback:
actionCallback(result);
break;
case Func<IDialogResult, Task> taskCallback:
await taskCallback(result);
break;
default:
throw new InvalidOperationException("The DialogCloseCallback has not been properly initialized. This must be initialized by the DialogService, and should not be set by user code.");
}
}
}
View on GitHub (pinned to 358118cd64)