agentleFS
vchelaruvchelaru/Gum/.claude/skills/gum-tool-errors/SKILL.md

gum-tool-errors

Skill655 starsChanged 2 months agoMITView on GitHub

Gum error detection/display. Triggers: Errors tab, '!' icons in tree view, ErrorChecker, ErrorViewModel, IErrorChecker, AllErrorsViewModel, MainErrorsPlugin, RequestErrorRefreshMessage, adding new error checks.

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    When an element file changes on disk, FileChangeReactionLogic.ReactToElementSaveChanged calls _pluginManager.ElementReloaded(element).

    line 73
  2. Very specific:

    Do not rely on ElementSelected alone for error refresh after reload: the reload path temporarily sets SelectedElement = null (to force a UI …

    line 75

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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

Plugin notification (VariableSet, InstanceAdd, StateAdd, Undo, ...)
    ↓
MainErrorsPlugin or MainTreeViewPlugin (never both for one notification)
    ↓
ErrorChecker.GetErrorsFor(element, project) → raises IErrorChecker.ErrorsChecked
    ├─ MainErrorsPlugin: fills AllErrorsViewModel.Errors (the Errors tab)
    └─ MainTreeViewPlugin.HandleErrorsChecked → ElementTreeViewManager.UpdateErrorIndicatorsForElement

The tree's "!" follows every full check through ErrorsChecked, including the Errors tab's.

Adding New Error Checks

Core check (missing references, structural problems): Add it to HeadlessErrorChecker.GetErrorsForInternal in Gum.ProjectServices, not the tool's Tools/Gum.Presentation/Managers/ErrorChecker.cs. The tool's checker delegates to the headless one (and converts ErrorResult → ErrorViewModel); putting checks in the headless layer means both the tool's Errors tab (per-selected-element refresh) and gumcli check (whole-project pass via GetAllErrors) surface them automatically. Pattern: iterate states/instances, emit new ErrorResult { ElementName = ..., Message = ..., Code = "GUM00XX", Severity = ... }. Register the code in ErrorDocsRegistry to get a help URL.

Project-level check (not tied to one element): add it to HeadlessErrorChecker.GetProjectErrors, not the per-element check. The Errors tab lists project-level rows whatever is selected, alongside the selected element's rows.

Plugin check (feature-specific, tool-side only): Subscribe to GetAllErrors in your plugin's StartUp(), return IEnumerable<ErrorViewModel>, and set item.OwnerPlugin = this on each. Plugin checks only show in the tool — the CLI doesn't load plugins. If the check should fire in CI / pre-commit, use the headless path above instead.

Fixable errors: set ActionName and ActionCommand on the ErrorViewModel to render a button beside the row that resolves the error in place (HasAction drives its visibility). An action that destroys anything unrecoverable still owes the user a confirmation before it runs.

Triggering refresh: Send RequestErrorRefreshMessage via messenger; the Errors tab re-checks the selected element and the tree icon follows.

Current Core Checks (ErrorChecker)

MethodWhat it detects
GetBehaviorErrorsForMissing behavior references; missing/wrong-type required instances and variables
GetMissingElementBaseTypeErrorForElement's own base type points to a deleted/nonexistent element
GetMissingBaseTypeErrorsForInstance's base type points to a nonexistent element
GetParentErrorsForParent variable references a nonexistent instance
GetInvalidVariableTypeErrorsForCustom variable uses an unknown or misnamed type (State suffix issues)
GetMissingSourceFileErrorsForGUM0004: element file missing on disk; GUM0008 when it exists under a different case
GetMissingExternalFileErrorsForGUM0006: referenced texture/font file missing (via GumProjectDependencyWalker); GUM0008 for a case-only difference
GetFontRangeEntryErrorsProject-level warnings: GUM0010 a font-specific FontRangeEntries entry no Text's font reaches, GUM0011 an entry whose range BmfcSave.GetIfIsValidRange rejects (BMFont bakes the default, KernSmith drops the unreadable parts). GUM0010 runs FontReferenceCollector (through FontRangeEntryChecker, which the Fonts settings page also uses) over the project only when such an entry exists
GetTextOutsideFontRangeErrorsForGUM0012 (warning): a literal Text value in any state has characters its font's ranges (GetFontRanges) leave out; skips pre-baked .fnt and GUM0011-invalid ranges
GetUnresolvableVariableReferenceErrorsForGUM0009 (warning): a VariableReferences line reads an element, instance or variable the project doesn't have, so it never applies. The end-to-end oracles fail on it despite the warning severity

Key Files

FilePurpose
Tools/Gum.ProjectServices/HeadlessErrorChecker.csAll core error checks
Tools/Gum.Presentation/Managers/ErrorChecker.csTool wrapper: headless checks + plugin checks; raises ErrorsChecked
Tools/Gum.Presentation/Managers/ErrorViewModel.csData model (Message, OwnerPlugin — object?, headless Gum.Presentation, ADR-0005)
Tools/Gum.Presentation/Plugins/InternalPlugins/Errors/MainErrorsPlugin.csErrors tab plugin; handles RequestErrorRefreshMessage
Tools/Gum.Presentation/Plugins/InternalPlugins/Errors/AllErrorsViewModel.csObservableCollection of errors; CountDescription for tab header (headless Gum.Presentation, ADR-0005)
Tool/TreeViewPlugin.Core/MainTreeViewPlugin.csTree "!" indicator; checks only on notifications the Errors tab doesn't
Tool/TreeViewPlugin.Core/ElementTreeViewManager.csUpdateErrorIndicatorsForElement
Tools/Gum.Presentation/Messages/RequestErrorRefreshMessage.csMessage to force an error refresh
Tests/Gum.Presentation.Tests/Managers/ErrorCheckerTests.csUnit 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

One check per notification: a check walks the element's file references and reads the disk, so a notification triggers a check in only one plugin. A new refresh trigger for the selected element goes in MainErrorsPlugin; the tree picks up the result. The tree only checks where the Errors tab doesn't (states, categories, undo, behavior instances, all elements on project load).

Case-check listings are cached: HeadlessErrorChecker keeps one FileNameCaseChecker for its lifetime. It re-reads a directory only when that directory's last-write time changes, so a new GUM0008 check doesn't need its own FileNameCaseChecker.

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.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.