ElectronNET/Electron.NET · error · ArgumentException

Argument must be greater then 0

Error message

Argument must be greater then 0

What it means

ProcessRunner.WaitAndKill waits for the spawned process to exit for up to timeoutMs milliseconds and then kills it. It validates that timeoutMs is strictly positive inside the timed-wait path and throws ArgumentException (note the message's typo 'then' for 'than') when timeoutMs <= 0, since a non-positive timeout cannot express a wait duration.

Solutions

  1. Pass a positive timeout in milliseconds, e.g. WaitAndKill(process, 5000).
  2. Fix the timeout computation so it cannot evaluate to <= 0 (use Math.Max(1, computed)).
  3. Set the configured timeout value in your settings source to a non-zero value.
  4. If 'wait indefinitely' was intended, use the runner's non-timed wait path/API instead of passing 0.

Example fix

// before
processRunner.WaitAndKill(process, timeoutMs);
// after
processRunner.WaitAndKill(process, Math.Max(1000, timeoutMs));
Defensive patterns

Strategy: validation

Validate before calling

if (timeoutMs <= 0)
    throw new ArgumentOutOfRangeException(nameof(timeoutMs), "Provide a positive timeout in milliseconds.");
processRunner.WaitAndKill(process, timeoutMs);

Try / catch

try
{
    processRunner.WaitAndKill(process, timeoutMs);
}
catch (ArgumentException ex) when (ex.ParamName == nameof(timeoutMs))
{
    Logger.Error("WaitAndKill requires timeoutMs > 0; check your timeout configuration.");
}

Prevention

When it happens

Trigger: Calling WaitAndKill with timeoutMs equal to 0, negative, or default(0) — e.g. passing Timeout.Infinite-style or computed values that evaluated to 0, or relying on a default int value.

Common situations: Config value for a process timeout read as 0 because the config key was missing/default; arithmetic on timeouts that underflowed; caller intending 'no timeout' passing 0 instead of a large value or the appropriate infinite constant; deserialized settings object with uninitialized int.

Related errors


AI-assisted analysis of ElectronNET/Electron.NET@87cc6f98b6 (2026-09-14). Data as JSON: /api/errors/7af288cd5ea86c43. Report an issue: GitHub.

Appendix: source

Thrown at src/ElectronNET.API/Common/ProcessRunner.cs:274

        /// <summary>Sychronously waits for the specified amount and ends the process afterwards.</summary>
        /// <param name="timeoutMs">The timeout ms.</param>
        /// <remarks>This method allows for a clean exit, since it also waits until the StandardOutput and
        /// StandardError pipes are processed to the end.</remarks>
        /// <returns>true, if the process has exited gracefully; false otherwise.</returns>
        public bool WaitAndKill(int timeoutMs)
        {
            var proc = this.process;

            if (proc == null)
            {
                return true;
            }

            try
            {
                if (timeoutMs <= 0)
                {
                    throw new ArgumentException("Argument must be greater then 0", nameof(timeoutMs));
                }

                // Timed waiting. We need to wait for I/O ourselves.
                if (!proc.WaitForExit(timeoutMs))
                {
                    this.Cancel();
                }

                // Wait for the I/O to finish.
                var waitMs = (int)(timeoutMs - this.stopwatch.ElapsedMilliseconds);
                waitMs = Math.Max(waitMs, 10);
                this.stdOutEvent?.WaitOne(waitMs);

                waitMs = (int)(timeoutMs - this.stopwatch.ElapsedMilliseconds);
                waitMs = Math.Max(waitMs, 10);
                return this.stdErrEvent?.WaitOne(waitMs) ?? false;
            }
            finally

View on GitHub (pinned to 87cc6f98b6)