The answer from @Tamas Tárnok led me down the right path, so I will mark he answer as the solution. It seems that if you use `job.Status.Failed = true`, the exception message will actually be displayed in a popup. Let me demonstrate: public class ImportCommand : Command { private readonly ICommandArgFactory _commandArgFactory; public ImportCommand( ICommandArgFactory commandArgFactory { if (commandArgFactory == null) throw new ArgumentNullException(nameof(commandArgFactory)); _commandArgFactory = commandArgFactory; } public override void Execute(CommandContext context) { NameValueCollection parameters = _commandArgFactory.GetArgs(context); Sitecore.Context.ClientPage.Start(this, "Import", new ClientPipelineArgs(parameters)); } private void Import(ClientPipelineArgs args) { if (args.IsPostBack) { if (args.Result == "no") return; ProgressBox.Execute("Import", "Import", DoImport, args); } else { SheerResponse.Confirm("Are you sure?"); args.WaitForPostBack(); } } private void DoImport(object[] parameters) { BaseJob job = Sitecore.Context.Job; if (job == null) return; try { ClientPipelineArgs args = parameters[0] as ClientPipelineArgs; job.Status.State = JobState.Running; ...code here... job.Status.AddMessage("Parsing some more..."); job.Status.State = JobState.Finished; } catch (CustomException customEx) { Log.Error(customEx.Message, this); job.Status.LogError(customEx.Message); job.Status.Failed = true; } catch (Exception ex) { Log.Error(ex.Message, this); job.Status.LogError(ex.Message); job.Status.Failed = true; } } }