gum-tool-errors

$npx mdskill add vchelaru/Gum/gum-tool-errors

Diagnose and display Gum project errors across tree views and tabs.

  • Enables agents to fix syntax issues and plugin failures in Gum projects.
  • Integrates with ErrorChecker, PluginManager, and ElementSave architecture.
  • Executes core checks and plugin events to aggregate error data.
  • Outputs error counts via icons and detailed lists in the Errors tab.

SKILL.md

.github/skills/gum-tool-errorsView on GitHub ↗
---
name: gum-tool-errors
description: Reference guide for Gum's error detection and display system. Load this when working on the Errors tab, error icons ("!" mark) in the tree view, ErrorChecker, ErrorViewModel, IErrorChecker, AllErrorsViewModel, MainErrorsPlugin, RequestErrorRefreshMessage, or adding new error checks.
---

# Gum Tool Error System Reference

## Architecture

Two tiers of error detection, merged into one display.

**Tier 1 — Core checks** (`ErrorChecker`): Runs on a given `ElementSave`. Called by both the tree view (icon refresh) and the Errors tab (list refresh).

**Tier 2 — Plugin checks**: Plugins implement `GetAllErrors` event (declared on `PluginBase`) and return `IEnumerable<ErrorViewModel>`. Called via `PluginManager.FillWithErrors()`, which is invoked at the end of `ErrorChecker.GetErrorsFor()`.

## Error Pipeline

```
User action (e.g. InstanceAdd, VariableSet, Undo)
    ↓
MainTreeViewPlugin → RefreshErrorIndicatorsForElement(element)
    ↓
ErrorChecker.GetErrorsFor(element, project)
    ↓
ElementTreeViewManager.UpdateErrorIndicatorsForElement()
    └─ Swaps icon to ExclamationIndex (6) if errors exist

SEPARATELY — Errors tab:
MainErrorsPlugin → UpdateErrorsForElement() or HandleErrorRefreshRequest()
    ↓
ErrorChecker.GetErrorsFor(element, project)
    ↓
AllErrorsViewModel.Errors (ObservableCollection) → ErrorDisplay.xaml ListBox
```

The tree icon refresh and the Errors tab refresh are independent. Both call `ErrorChecker.GetErrorsFor` but are triggered separately.

## Adding New Error Checks

**Core check** (missing references, structural problems): Add a private method to `ErrorChecker` and call it from `GetErrorsFor`. Pattern: iterate states/instances, add `new ErrorViewModel { Message = "..." }`.

**Plugin check** (feature-specific): Subscribe to `GetAllErrors` in your plugin's `StartUp()`, return `IEnumerable<ErrorViewModel>`, and set `item.OwnerPlugin = this` on each.

**Triggering refresh**: Send `RequestErrorRefreshMessage` via messenger to refresh the Errors tab list. Tree icon refresh is driven by existing plugin event subscriptions in `MainTreeViewPlugin`.

## Current Core Checks (ErrorChecker)

| Method | What it detects |
|--------|----------------|
| `GetBehaviorErrorsFor` | Missing behavior references; missing/wrong-type required instances and variables |
| `GetMissingElementBaseTypeErrorFor` | Element's own base type points to a deleted/nonexistent element |
| `GetMissingBaseTypeErrorsFor` | Instance's base type points to a nonexistent element |
| `GetParentErrorsFor` | Parent variable references a nonexistent instance |
| `GetInvalidVariableTypeErrorsFor` | Custom variable uses an unknown or misnamed type (State suffix issues) |

## Key Files

| File | Purpose |
|------|---------|
| `Gum/Managers/ErrorChecker.cs` | All core error checks |
| `Gum/Managers/ErrorViewModel.cs` | Data model (`Message`, `OwnerPlugin`) |
| `Gum/Managers/IErrorChecker.cs` | Interface |
| `Gum/Plugins/InternalPlugins/Errors/MainErrorsPlugin.cs` | Errors tab plugin; handles `RequestErrorRefreshMessage` |
| `Gum/Plugins/InternalPlugins/Errors/AllErrorsViewModel.cs` | ObservableCollection of errors; `CountDescription` for tab header |
| `Gum/Plugins/InternalPlugins/TreeView/ElementTreeViewManager.cs` | `UpdateErrorIndicatorsForElement`; `ExclamationIndex = 6` |
| `Gum/Messages/RequestErrorRefreshMessage.cs` | Message to force Errors tab refresh |
| `Tool/Tests/GumToolUnitTests/Managers/ErrorCheckerTests.cs` | Unit tests for ErrorChecker |

## Element Reload and Errors

When an element file changes on disk, `FileChangeReactionLogic.ReactToElementSaveChanged` calls `_pluginManager.ElementReloaded(element)`. `MainErrorsPlugin` subscribes to `ElementReloaded` and calls `UpdateErrorsForElement` — this is the correct trigger for refreshing errors after a reload.

Do **not** rely on `ElementSelected` alone for error refresh after reload: the reload path temporarily sets `SelectedElement = null` (to force a UI reset), which clears errors, and the subsequent re-selection uses `file.StandardizedNoPathNoExtension` which fails to find elements in subfolders — so errors would never be repopulated.

## Non-Obvious Behaviors

**Two separate refreshes**: The "!" icon in the tree and the Errors tab list are populated independently. Changing `ErrorChecker` automatically affects both, but only if the right events trigger both refresh paths.

**Cache wrapping**: `ErrorChecker.GetErrorsFor` wraps its checks in `ObjectFinder.Self.EnableCache()` / `DisableCache()`. New checks added inside the method benefit from this automatically.

**`IsSourceFileMissing` is separate**: The tree view shows "!" if `element.IsSourceFileMissing || hasErrors`. Source file missing is not surfaced as an `ErrorViewModel` — it's a flag on the element itself, checked directly by `UpdateErrorIndicatorsForElement`.

More from vchelaru/Gum

SkillDescription
bump-nuget-versionBump the NuGet package versions for all 12 Gum projects (11 libraries + GumCli). Queries NuGet to check if a version exists for today, then sets the new version to YYYY.M.D.V where V increments from the latest published version today (or starts at 1). Creates a release branch named ReleaseCode_YYYY_M_D_V, commits the changes, and pushes. Run this before triggering the nuget release workflow.
gum-cliReference guide for GumCli — the headless command-line tool for Gum projects. Load this when working on gumcli commands (new, check, codegen, codegen-init), Gum.ProjectServices, HeadlessErrorChecker, ProjectLoader, HeadlessCodeGenerationService, CodeGenerationAutoSetupService, or the FormsTemplateCreator.
gum-docs-writingReference guide for writing Gum documentation in GitBook markdown. Load when writing or editing docs/ files, adding pages to SUMMARY.md, using GitBook hints/figures, linking between pages, or adding images.
gum-forms-behaviorsCovers Gum's behaviors system and the design-time → runtime Forms wrapping lifecycle. Load this when working on BehaviorSave, ElementBehaviorReference, StandardFormsBehaviorNames, FormsUtilities.RegisterFromFileFormRuntimeDefaults, DefaultFromFileXxxRuntime classes, or when investigating why Forms properties cannot be set at design time in the Gum tool.
gum-forms-controlsReference guide for Forms controls — classes inheriting from FrameworkElement. Load this when working on Button, CheckBox, ListBox, ComboBox, TextBox, ScrollViewer, or any class in Gum.Forms.Controls (or FlatRedBall.Forms.Controls). Also load when working on FrameworkElement itself, the Visual/InteractiveGue relationship, state machines, DefaultVisuals, or ReactToVisualChanged.
gum-forms-default-visualsReference guide for Forms DefaultVisuals — the code-only visual classes that back Forms controls. Load when working on ButtonVisual, any *Visual class in DefaultVisuals/, Styling, DefaultFormsTemplates registration, or building custom code-only Forms visuals.
gum-forms-itemscontrolReference guide for ItemsControl and ListBox — the Items/ListBoxItems relationship, templates, InnerPanel sync, and gotchas. Load this when working on ItemsControl, ListBox, ListBoxItem, VisualTemplate, FrameworkElementTemplate, Items collection behavior, ListBoxItems desync, or adding/removing items from a list box.
gum-layout>
gum-layout-engine>
gum-localizationReference guide for Gum's runtime localization system — ILocalizationService, CSV/RESX loading, Text vs TextNoTranslate paths, Forms control localization patterns, and gotchas.