d2phap/ImageGlass · warning · ArgumentException

Button executable required.

Error message

Button executable required.

What it means

Thrown in FrmSettings (Tab Toolbar handler) when a parsed ToolbarItemModel has Type 'Button' but btn.OnClick.Executable is null or empty. It is an ArgumentException with paramName 'btn.OnClick.Executable'; the message comes from the localized resource FrmSettings.Toolbar._Errors._ButtonExecutableRequired. The exception is caught by the surrounding try/catch and shown via Config.ShowError.

Source

Thrown at v9/ImageGlass/FrmSettings.cs:256

                var btn = BHelper.ParseJson<ToolbarItemModel>(e.Data);

                if (btn.Type == ToolbarItemModelType.Button)
                {
                    var langPath = $"{nameof(FrmSettings)}.Toolbar._Errors";
                    if (string.IsNullOrWhiteSpace(btn.Id))
                    {
                        throw new ArgumentException(Config.Language[$"{langPath}._ButtonIdRequired"], nameof(btn.Id));
                    }

                    if (isCreate
                        && Config.ToolbarButtons.Any(i => i.Id.Equals(btn.Id, StringComparison.OrdinalIgnoreCase)))
                    {
                        throw new ArgumentException(ZString.Format(Config.Language[$"{langPath}._ButtonIdDuplicated"], btn.Id), nameof(btn.Id));
                    }

                    if (string.IsNullOrEmpty(btn.OnClick.Executable))
                    {
                        throw new ArgumentException(Config.Language[$"{langPath}._ButtonExecutableRequired"], nameof(btn.OnClick.Executable));
                    }
                }
            }
            catch (Exception ex)
            {
                _ = Config.ShowError(this, title: Config.Language["_._Error"], heading: ex.Message);
                isValid = false;
            }

            Web2.PostWeb2Message(e.Name, BHelper.ToJson(isValid));
        }
        #endregion // Tab Toolbar


        // Tab File type associations
        #region Tab File type associations
        else if (e.Name.Equals("Btn_OpenExtIconFolder", StringComparison.Ordinal))
        {

View on GitHub (pinned to 4a3c4fecef)

Solutions

  1. Set btn.OnClick.Executable to the full path of the program to launch before submitting.
  2. Add client-side validation so submit is disabled until the Executable field is non-empty.
  3. When cloning an existing button, copy the Executable field across rather than leaving OnClick default-constructed.
  4. Resolve the path against PATH or %ProgramFiles% and confirm the file exists before submit.

Example fix

// before
var btn = new ToolbarItemModel
{
    Type = ToolbarItemModelType.Button,
    Id = "open-notepad",
    OnClick = new ToolbarClickAction { Arguments = "%1" }, // Executable missing
};

// after
var btn = new ToolbarItemModel
{
    Type = ToolbarItemModelType.Button,
    Id = "open-notepad",
    OnClick = new ToolbarClickAction { Executable = @"C:\Windows\System32\notepad.exe", Arguments = "%1" },
};
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the OnClick executable is set before submission
static bool HasExecutable(ToolbarItemModel btn, out string error)
{
    error = null;
    if (btn?.Type != ToolbarItemModelType.Button) return true;
    if (btn.OnClick == null || string.IsNullOrEmpty(btn.OnClick.Executable))
    {
        error = "Button executable is required.";
        return false;
    }
    return true;
}

Type guard

static bool IsCompleteButton(ToolbarItemModel btn) =>
    btn != null
    && btn.Type == ToolbarItemModelType.Button
    && !string.IsNullOrWhiteSpace(btn.Id)
    && btn.OnClick != null
    && !string.IsNullOrEmpty(btn.OnClick.Executable);

Try / catch

try
{
    var btn = BHelper.ParseJson<ToolbarItemModel>(e.Data);
    // ...validation...
}
catch (ArgumentException ex) when (ex.ParamName == "btn.OnClick.Executable")
{
    // Already shown via Config.ShowError; mark the form invalid.
    isValid = false;
}

Prevention

When it happens

Trigger: The Web2 create/edit toolbar message submits a button whose OnClick object has no Executable (e.g. only Arguments or WorkingDirectory are set); the OnClick object is omitted from the JSON so Executable defaults to empty; or the executable path string is blank.

Common situations: A user configures arguments/working directory but forgets the program path; a template ships with OnClick partially populated; or the front-end form validates the Id but not the Executable field.

Related errors


AI-assisted analysis of d2phap/ImageGlass@4a3c4fecef (2026-08-13). Data as JSON: /api/errors/13e1adab008c5b4c. Report an issue: GitHub.