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.

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.