Code addon troubleshooting

Trace activation, dependency, readiness, registry, network, storage and teardown failures from their actual contracts.

Activation failures

SymptomCheck
No implementation foundThe class is public, implements ILitherarpAddon, has [LitherarpAddon("id")], and the published revision includes its .cll.
Identity mismatchAttribute, AddonId, manifest AddonId and operator entry id normalize to the same value.
Protocol mismatchImplementation and manifest ProtocolVersion are equal and positive.
Dependency plan rejectedRead lastMessage for missing required ids, invalid SemVer constraints, conflicts or a cycle.
Code gate refusedGlobal allowCodeAddons, per-entry allowCode, enabled flags and parent package are all correct.
Revision driftReapply the manifest revision and confirm required package revisions. Do not mix a stale package cache with a newer operator entry.
Loading timed outEach async loading callback must finish within 15 seconds and honor its cancellation token.
Package operation timed outPackage fetch, mount, manifest and cloud-resource operations each have a fixed 30-second budget. Check connectivity, package visibility and the pinned revision before retrying.

Client readiness

SymptomCheck
Client waits before spawnThe client is mounting the exact required package and code snapshot. Inspect client logs for the first required failure.
Client is kicked on timeoutIncrease clientReadinessTimeoutSeconds only after measuring legitimate load time. The valid range is 15 to 300.
Client reports a different fingerprintA hot apply superseded its older snapshot. Let the new generation finish; stale acknowledgements are ignored.
Local package works only for hostThis is expected. Remote clients never mount local.*. Publish a revision for multi-client tests.

Runtime behavior

SymptomCheck
Public section did not changeCall InvalidatePublicSnapshot after provider state changes. Registered config reload callbacks do this automatically.
Player section rejectedMeasure serialized UTF-8 bytes, not character count. Keep it at or below 8,000 bytes.
Network handler never runsMatch addon id, normalized message name, direction and registered realm. Client-to-host delivery needs a positive caller Steam id and rate budget. A caller pawn is required only when PermissionNode is configured.
Public snapshot failsKeep each addon-provided section at or below 8,000 UTF-8 bytes. The core addons section is limited to 4,194,304 bytes and the complete snapshot to 8,388,608 bytes.
Event handler stops runningThree consecutive recoverable failures quarantine it. Fix the exception and recreate the subscription by reapplying the addon.
Registry layer rejectedThe key is valid, priority is between -1000 and 1000, the addon does not already own that key, and another owner does not hold the same key and priority.
Versioned load failedInspect LitherarpAddonDataResult.Error. Supply a migration for every stored schema version you accept.
Admin page is visible but action is deniedPage access and host action authorization are separate. Grant and check the same addon.<id>.<node> on the host.

Disable and reapply

Confirm that subscriptions were passed to Track, custom objects to TrackGameObject, components to TrackComponent, and background work to TrackCancellation. Use realm-specific shutdown or OnTeardown for anything else.

Mounted bytes and static fields can remain cached until restart. If disabled behavior remains active, first prove whether it is an untracked callback or object. A cached asset byte alone does not retain a context registration.