-
Notifications
You must be signed in to change notification settings - Fork 0
Troubleshooting
Jim Daley edited this page May 1, 2026
·
3 revisions
Start with the runtime phase where the symptom appears: discovery, compatibility, entitlement, registry resolution, lifecycle, or UI surface rendering.
flowchart TD
Symptom["Observed failure"] --> Discover{"Manifest discovered?"}
Discover -- no --> ManifestFix["Check bundle path and JSON schema"]
Discover -- yes --> Compatible{"Compatibility report clean?"}
Compatible -- no --> CompatFix["Fix schema, platform, version, or capability"]
Compatible -- yes --> Unlocked{"Entitlement unlocked?"}
Unlocked -- no --> EntFix["Check iapProductID and provider state"]
Unlocked -- yes --> Factory{"Registry factory found?"}
Factory -- no --> RegFix["Register matching entryPoint"]
Factory -- yes --> Lifecycle{"start(context) succeeds?"}
Lifecycle -- no --> StartFix["Inspect module error logs"]
Lifecycle -- yes --> UI{"UI visible?"}
UI -- no --> UIFix["Check active UI module, viewID, slot, and registry"]
UI -- yes --> Done["Runtime path healthy"]
| Symptom | Likely Cause | Fix |
|---|---|---|
| No modules discovered | Manifest files are not bundled under ForsettiManifests. |
Check target membership and resource path. |
validationFailed |
Manifest JSON is malformed or missing required fields. | Validate JSON and compare with the schema page. |
duplicateModuleID |
Two manifests share the same moduleID. |
Make module IDs globally unique. |
incompatible(report:) |
Platform/version/capability check failed. | Inspect compatibility issues and fix the manifest or policy. |
moduleLocked |
Entitlement provider returned locked. | Verify iapProductID, StoreKit state, or static unlock IDs. |
moduleIdentityMismatch |
Factory returned a module whose descriptor or manifest does not match the discovered manifest. | Align descriptor, bundled manifest, and registry entry point. |
missingCapability |
Module contributed UI or resolved a service without the required capability. | Add the required capability to the manifest or remove the contribution/service use. |
notUIModule |
Manifest says ui or app, but factory returned a plain ForsettiModule. |
Return a ForsettiUIModule or ForsettiAppModule. |
| Active UI module not visible | Activation did not succeed or injected view is not registered. | Check activeUIModuleID, activation errors, and viewID registration. |
| Toolbar route fails | Pointer/route ID missing or destination/slot unsupported. | Check active OverlaySchema and host catalogs. |
| Module messages not received | Target payload does not match subscriber module ID. | Use sendModuleMessage and subscribe with the target ID. |
flowchart LR
Path["Resource path"] --> Fields["Required fields"]
Fields --> Types["moduleType and platforms"]
Types --> Version["Forsetti version range"]
Version --> Caps["capabilitiesRequested"]
Caps --> Entry["entryPoint"]
Required manifest root keys:
schemaVersionmoduleIDdisplayNamemoduleVersionmoduleTypesupportedPlatformsminForsettiVersioncapabilitiesRequestedentryPoint
| Log Source | Useful For |
|---|---|
ConsoleForsettiLogger in debug builds |
Activation, deactivation, and module lifecycle messages. |
ForsettiHostController.errorMessage |
User-visible controller failures. |
ForsettiHostOverlayRouter.lastOutcome |
Pointer and route resolution failures. |
| Compatibility report | Exact reason activation cannot proceed. |
| Platform logger | Production-capable runtime diagnostics where OSLog is available. |
- Reproduce with the smallest manifest and module set.
- Confirm the manifest loads.
- Confirm compatibility is clean.
- Confirm entitlement unlock state.
- Confirm the registry entry point.
- Confirm module lifecycle behavior.
- Confirm UI contribution rendering.
- Add a focused regression test.