MyronCMS Developers Hub Docs sandbox review

Cookbook

Load Errors And Recovery

Extension load failures are captured so the rest of MyronCMS can continue running while the operator can see what failed. Use this recipe when an extension is registered but not loaded, its admin route is missing, or its actions do not appear.

Use Case

An extension is present under app/extensions/{vendor}/, but Installed Extensions shows:

Not loaded

or displays a latest load error.

Human Path

Open:

/extensions

Review:

  • vendor,
  • enabled/disabled state,
  • granted scopes,
  • directory presence,
  • loaded/not loaded state,
  • latest load error.

Depending on the failure, an administrator can:

  • enable the extension,
  • disable the extension,
  • revoke an individual granted scope,
  • return to Register Extension to create or refresh the grant.

Local code or manifest fixes still happen in the repository.

AI Path

An AI coding agent can:

  • inspect manifest.json,
  • fix local PHP or migration files,
  • ensure route and migration paths are valid,
  • run verification,
  • explain what an administrator needs to review in /extensions.

An installed MCP client must not enable the extension, grant itself scopes, revoke trust gates, or bypass CSRF/admin-only forms. Runtime recovery through Installed Extensions is human-admin-only.

How Errors Are Recorded

During MyronExtensionLoader::boot(), the loader catches manifest, migration, bootstrap, and contribution registration failures.

On failure, it:

  1. stores the message in memory for that boot,
  2. writes a row through ExtensionScopeGrantRepository::recordLoadError(),
  3. continues loading other extensions and core routes.

On successful load, it calls:

$this->grants->clearLoadErrors($manifest->vendor);

That clears previous persisted errors for the vendor.

How Errors Surface

Installed Extensions uses:

myronExtensionLoader()->statuses();

The status includes:

FieldMeaning
enabledWhether the grant row is enabled.
grantedScopesScopes recorded for the vendor grant.
directoryExistsWhether the extension directory is present.
manifestFoundWhether the manifest parsed for this boot.
loadedWhether the manifest exists, no load failure was recorded, and the grant is enabled.
lastErrorLatest persisted or in-memory load error message.

The page renders load health and latest error text in the browser.

Scopes

Load recovery itself is not an MCP or action call. Extension grant and enablement are administrator workflows.

The underlying load failure can still be scope-related. If a manifest requires content.write but the grant only includes content.read, the loader records an ungranted-scope failure.

Artifacts

Admin surfaces:

  • /extensions
  • /extensions/register

Database tables:

  • extension_scope_grants
  • extension_load_errors

Local files:

  • app/extensions/{vendor}/manifest.json
  • app/extensions/{vendor}/bootstrap.php
  • app/extensions/{vendor}/migrations/*.php
  • app/extensions/{vendor}/admin/routes/*.php

Safety Boundary

Do not treat a load error as permission to weaken the system. Safe recovery is to fix the local extension package or have an administrator adjust the grant.

Do not:

  • edit database grant rows directly,
  • remove CSRF checks,
  • skip myronRequireAdministrationAccess(),
  • broaden caller scopes from an MCP client,
  • bypass the loader to register actions manually.

Verification

Run:

php app/tests/verify-extension-system-foundation.php

The foundation test verifies that:

  • an unregistered extension is skipped,
  • a registered reference extension loads,
  • a bootstrap exception is recorded as a load error,
  • Installed Extensions route keys resolve,
  • the Extensions rail section is administrator-only.

For a real recovery, verify:

  1. the local fix is present,
  2. the extension is registered and enabled,
  3. the required manifest scopes are granted,
  4. the page no longer shows the previous load error after a successful load,
  5. actions or admin routes appear only if their source files and grants are valid.

Failure Modes

SymptomLikely causeSafe remediation
Extension does not appear in runtime actionsExtension is unregistered, disabled, under-granted, or failed during boot.Review /extensions, fix local files, and confirm grants.
Directory missingGrant exists but local extension directory is absent.Restore the local extension directory or disable the grant.
Manifest missing or invalidmanifest.json is absent or invalid JSON/schema.Fix the manifest; keep vendor and directory aligned.
Load error mentions ungranted scopeManifest requires a scope not granted by the operator.Administrator reviews the grant; do not self-broaden through MCP.
Migration failureMigration touched a non-prefixed table or threw.Fix migration under {vendor}_*; rerun through normal load.
Bootstrap throwsPHP error or explicit exception in bootstrap.php.Fix the bootstrap or contributed class.
Admin route missingHandler file is missing or extension did not load.Fix the route path and load state.
Old load error still visibleExtension has not successfully loaded since the fix.Trigger normal runtime boot and confirm the vendor loads cleanly.

Recovery Checklist

  1. Confirm the vendor directory exists.
  2. Validate manifest.json.
  3. Confirm the grant exists in /extensions/register or /extensions.
  4. Confirm the extension is enabled.
  5. Confirm granted scopes cover manifest requiredScopes.
  6. Review migrations for {vendor}_* table isolation.
  7. Review bootstrap.php and contributed classes for thrown exceptions.
  8. Run the foundation test.
  9. Reload Installed Extensions and confirm the old error is gone.