{"record":{"id":"d3246636413307e6","repo":"PrismLibrary/Prism","slug":"at-least-one-button-needs-to-be-supplied","errorCode":null,"errorMessage":"At least one button needs to be supplied","messagePattern":"At least one button needs to be supplied","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Maui/Prism.Maui/Services/PageDialogs/PageDialogService.cs","lineNumber":150,"sourceCode":"    {\n        await DisplayActionSheetAsync(title, FlowDirection.MatchParent, buttons);\n    }\n\n    /// <summary>\n    /// Displays a native platform action sheet, allowing the application user to choose from several buttons.\n    /// </summary>\n    /// <para>\n    /// The text displayed in the action sheet will be the value for <see cref=\"IActionSheetButton.Text\"/> and when pressed\n    /// the callback action will be executed.\n    /// </para>\n    /// <param name=\"title\">Text to display in action sheet</param>\n    /// <param name=\"flowDirection\">The Text flow direction.</param>\n    /// <param name=\"buttons\">Buttons displayed in action sheet</param>\n    /// <returns></returns>\n    public virtual async Task DisplayActionSheetAsync(string title, FlowDirection flowDirection, params IActionSheetButton[] buttons)\n    {\n        if (buttons == null || buttons.All(b => b == null))\n            throw new ArgumentException(\"At least one button needs to be supplied\", nameof(buttons));\n\n        var destroyButton = buttons.FirstOrDefault(button => button != null && button.IsDestroy);\n        var cancelButton = buttons.FirstOrDefault(button => button != null && button.IsCancel);\n        var otherButtonsText = buttons.Where(button => button != null && !(button.IsDestroy || button.IsCancel)).Select(b => b.Text).ToArray();\n\n        var pressedButton = await DisplayActionSheetAsync(title, cancelButton?.Text, destroyButton?.Text, flowDirection, otherButtonsText);\n\n        foreach (var button in buttons.Where(button => button != null && button.Text.Equals(pressedButton)))\n        {\n            await button.PressButton();\n            return;\n        }\n    }\n\n    /// <summary>\n    /// Displays a native platform prompt, allowing the application user to enter a string.\n    /// </summary>\n    /// <param name=\"title\">Title to display</param>","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Maui/Prism.Maui/Services/PageDialogs/PageDialogService.cs#L132-L168","documentation":"PageDialogService.DisplayActionSheetAsync validates that at least one non-null IActionSheetButton was supplied. If the buttons array is null or all entries are null, it throws an ArgumentException naming the buttons parameter, because an action sheet with no actions is meaningless.","triggerScenarios":"Calling DisplayActionSheetAsync(title, flowDirection, (IActionSheetButton[])null) or passing buttons built from an empty/dynamic list where every entry ended up null (e.g. FromAction/FromCancel constructed from null delegates or empty collections).","commonSituations":"Building action sheet buttons conditionally from a list that turned out empty; spreading an array with all-null elements; passing a params array variable that was never initialized.","solutions":["Ensure you pass at least one button via IActionSheetButton.FromAction / FromCancel / FromDestroy.","Guard dynamic button lists: if the computed list is empty, show an alert instead or add a default cancel button.","Filter out null buttons before calling, and short-circuit if nothing remains.","Check that factory calls like IActionSheetButton.FromAction(...) are not themselves returning null due to overloads."],"exampleFix":"// before\nawait _dialogs.DisplayActionSheetAsync(\"Options\", FlowDirection.MatchParent, buttons);\n// after\nif (buttons is { Length: > 0 })\n    await _dialogs.DisplayActionSheetAsync(\"Options\", FlowDirection.MatchParent, buttons);\nelse\n    await _dialogs.DisplayActionSheetAsync(\"No options available\", FlowDirection.MatchParent,\n        IActionSheetButton.CancelButton(() => { }));","handlingStrategy":"validation","validationCode":"bool hasButtons = buttons is { Length: > 0 } && buttons.Any(b => b != null);\nif (!hasButtons) throw new ArgumentException(\"At least one button required\");","typeGuard":"static bool HasActionSheetButtons(IActionSheetButton[]? b) =>\n    b is { Length: > 0 } && b.Any(x => x is not null);","tryCatchPattern":"try\n{\n    await _dialogs.DisplayActionSheetAsync(title, FlowDirection.MatchParent, buttons);\n}\ncatch (ArgumentException)\n{\n    await _dialogs.DisplayAlertAsync(title, message, \"OK\");\n}","preventionTips":["Never pass a null/empty params array; always include at least a cancel button.","Filter nulls from dynamically built button lists before display.","Wrap dialog calls behind your own service that enforces non-empty buttons."],"tags":["dotnet","maui","prism","dialogs","arguments"],"backgroundTag":"empty-required-field","analyzedSha":"358118cd640d9a22ff8cf21c8ad197fa038b7990","analyzedAt":"2026-09-15T15:00:31.079Z","contentChangedAt":"2026-09-15T15:00:31.079Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}