JosefNemec/Playnite · error · ScriptRuntimeException

e.Message

Error message

e.Message

What it means

Re-thrown from PowerShellRuntime.Execute when pipe.Invoke() raises a System.Management.Automation.RuntimeException. The catch wraps the PS error message and ScriptStackTrace into a ScriptRuntimeException, preserving PowerShell's diagnostic detail for the caller to surface.

Source

Thrown at source/Playnite/Scripting/PowerShell/PowerShell.cs:206

                using (var pipe = runspace.CreatePipeline(script))
                {
                    if (variables != null)
                    {
                        foreach (var key in variables.Keys)
                        {
                            runspace.SessionStateProxy.SetVariable(key, variables[key]);
                        }
                    }

                    Collection<PSObject> result = null;

                    try
                    {
                        result = pipe.Invoke();
                    }
                    catch (RuntimeException e)
                    {
                        throw new ScriptRuntimeException(e.Message, e.ErrorRecord.ScriptStackTrace);
                    }

                    if (result == null)
                    {
                        return null;
                    }
                    else
                    {
                        if (result.Count == 1)
                        {
                            return result[0]?.BaseObject;
                        }
                        else
                        {
                            return result.Select(a => a?.BaseObject).ToList();
                        }
                    }
                }

View on GitHub (pinned to 5911f4e964)

Solutions

  1. Read ScriptRuntimeException.ScriptStackTrace to locate the failing line/command in the user script.
  2. Run the script standalone in a PowerShell host with the same variables to reproduce, then fix the offending cmdlet/type/null access.
  3. Ensure any module the script depends on is Import-Module'd before execution.
  4. Set ErrorActionPreference appropriately or wrap fragile regions in try/catch within the PS script.

Example fix

// caller pattern (already used in MainViewModelBase.RunAppScript):
try
{
    runtime.Execute(script, workDir, vars);
}
catch (ScriptRuntimeException ex)
{
    Logger.Error(ex, $"Script failed: {ex.Message}\n{ex.ScriptStackTrace}");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the script compiles/imports before executing user content where possible:
if (string.IsNullOrWhiteSpace(script)) return;
// (full pre-validation of arbitrary PS is impractical — rely on try/catch at execution)

Type guard

static bool LooksLikeValidScript(string s) => !string.IsNullOrWhiteSpace(s) && !s.Contains("\0");

Try / catch

try { runtime.Execute(script, workDir, vars); }
catch (ScriptRuntimeException ex)
{
    Logger.Error($"PS script failed: {ex.Message}\n{ex.ScriptStackTrace}");
    Dialogs.ShowMessage($"Script error:\n{ex.Message}\n\n{ex.ScriptStackTrace}", image: MessageBoxImage.Error);
}

Prevention

When it happens

Trigger: PowerShellRuntime.Execute(script, ...) runs a script via runspace.CreatePipeline(script).Invoke(); the script throws at runtime (cmdlet not found, type error, divide-by-zero, null dereference, etc.), producing a RuntimeException that the catch at line 204 wraps.

Common situations: Extension/automation script calls an undefined cmdlet or function, references $null members, uses a type not loaded, or violates ErrorActionPreference='Stop' set at line 115. A script written for newer PowerShell API calls missing on the user's machine. Bad variable passed in via the variables dictionary.

Related errors


AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13). Data as JSON: /api/errors/94fa2e41436345c9. Report an issue: GitHub.