Troubleshooting
Symptoms, causes and fixes for the problems reported most often
Most issues fall into a handful of categories: restore/build configuration, rendering and interaction details, serialization of custom types, and automation or extension setup. Each entry below states the symptom, the cause and the fix.
Table of Contents
Restore and Build
"Unable to find package TheTechIdea.Beep.DataManagementModels 3.1.1"
Cause: the framework depends on BeepDM model packages that are not published on nuget.org at the required versions.
Fix: add the private feed that hosts the TheTechIdea.Beep.* packages (a local folder feed or your internal server) to nuget.config before restoring. The same feed is required in CI.
NU1701 when referencing the WinForms or WPF host packages
Cause: SkiaSharp 4.x view packages ship no net8.0 assets, so older Windows TFMs silently fall back to .NET Framework assemblies.
Fix: target net10.0-windows10.0.19041.0 (or the matching net9.0-windows10.0.19041.0) for the Windows hosts. Do not suppress NU1701 — the warning is telling you the wrong assets were chosen.
MAUI project fails to build on a machine without workloads
Cause: the MAUI head requires the maui workload, which CI agents often lack.
Fix: build through the CI filter (Beep.Skia.CI.slnf), which excludes the MAUI project; install the workload locally if you need that head.
CS1591 or documentation warnings in the build
Cause: libraries generate XML documentation, and some public members have no /// comment.
Fix: nothing to do — the repository suppresses CS1591 so the build stays warning-free while still shipping the XML file for IntelliSense. Add comments where they help; the Help site's API reference covers the whole surface.
Rendering and Interaction
Connection lines detach from a custom component after it moves
Cause: the component's port layout was not marked stale, so ports kept their old coordinates.
Fix: mark ports dirty whenever geometry that affects them changes, and lay them out lazily in the draw path:
protected override void DrawContent(SKCanvas canvas, DrawingContext context)
{
EnsurePortLayout(() => LayoutPorts());
// ... draw
}
Dropped components land offset from the cursor
Cause: the pointer position was treated as world coordinates. The canvas is panned and zoomed.
Fix: convert screen to world with the viewport before assigning X/Y:
float zoom = drawingManager.Zoom == 0 ? 1f : drawingManager.Zoom;
component.X = (screen.X - drawingManager.PanOffset.X) / zoom;
component.Y = (screen.Y - drawingManager.PanOffset.Y) / zoom;
Theme changes do not repaint the canvas
Cause: the theme is read while drawing, but nothing requested a frame.
Fix: request a redraw after switching themes (or subscribe to ThemeManager.ThemeChanged and do it centrally).
ThemeManager.ApplyTheme("Dark");
drawingManager.RequestRedraw();
Large diagrams drop frames
Cause: per-frame allocations and shadows dominate the render loop.
Fix: reuse SKPaint instances instead of allocating in DrawContent, set Elevation = 0 on components that do not need depth, and keep viewport culling enabled (the renderer skips components outside the visible rect). See the Performance Guide for measured numbers.
Serialization
Saved diagrams lose custom components on load
Cause: ComponentDto.Type stores an assembly-qualified type name; if the assembly is not loaded, LoadFromDto skips the component.
Fix: load the extension or assembly that defines the type before calling LoadFromDto, and never rename component classes after release.
Complex property values come back as strings
Cause: the value was stored in PropertyBag (string bag) instead of TypedPropertyBag.
Fix: ToDto() already routes non-convertible values into TypedPropertyBag. If you build DTOs by hand, do the same: simple values to PropertyBag, everything else through JsonSerializer.SerializeToElement.
Loading an old file fails or drops properties
Cause: the payload uses an earlier SchemaVersion.
Fix: loading is tolerant — missing bags are treated as empty. Check dto.SchemaVersion if you need custom upgrade logic; see Serialization.
Automation
A workflow completes but nothing happened
Cause: the diagram contains components that are not automation nodes, or the nodes are not connected in dependency order.
Fix: use AutomationNode-derived components (see Automation Nodes) and connect them so the engine can sort them topologically. Inspect the run result for per-node states.
Credentials appear in the diagram file
Cause: secrets were written into NodeProperties.
Fix: store secrets in the credential vault and reference them by name; see Credentials & Connections.
Extensions
An installed extension does not appear in the palette
Cause: the extension assembly was never loaded, or the palette was not refreshed.
Fix: load the directories reported by ExtensionPackageManager.GetLoadDirectories() through SkiaExtensionHost, then call palette.LoadComponentsFromRegistry() again.
Installing a package fails
Cause: the .beepkg is malformed, targets an incompatible version, or was rejected by the archive safety checks (path traversal, oversized entries).
Fix: read the error on the ExtensionInstallResult; it names the failed gate. Rebuild the package with the current packaging tooling.
Testing
Tests pass individually but fail in a suite
Cause: Skia native state is process-wide; parallel test execution can corrupt it.
Fix: the repository disables test parallelization in TestAssemblyInfo.cs. Keep that setting for any project that renders.
Rendering a component in a test draws nothing
Cause: components cull against the drawing context bounds, and an empty viewport culls everything.
Fix: draw through a DrawingManager with a real surface (or pass a real viewport) rather than calling the draw entry point with default bounds.