moeru-ai/airi · error · Error

Extension manifest not found: ${extensionId}

Error message

Extension manifest not found: ${extensionId}

What it means

Thrown by loadExtensionById when extensionRegistry.findManifestEntry(extensionId) returns nothing, meaning no discovered extension manifest matches the requested id. The registry is built during extension discovery/scanning, so a missing entry means the extension was never found on disk or not registered.

Source

Thrown at apps/stage-tamagotchi/src/main/services/airi/plugins/host/index.ts:353

      entries: extensionRegistry.listEntries(),
      config: getConfig(),
      loaded,
      manifestEntryByExtensionId: extensionRegistry.getManifestEntryByExtensionId(),
      extensionAssetService: extensionAssetSnapshotService,
    })
  }

  const loadExtensionById = async (
    extensionId: string,
    loadOptions: { cacheBustKey?: string } = {},
  ) => {
    if (loaded.has(extensionId)) {
      return
    }

    const entry = extensionRegistry.findManifestEntry(extensionId)
    if (!entry) {
      throw new Error(`Extension manifest not found: ${extensionId}`)
    }

    const manifestForLoad = createManifestForLoad(entry, loadOptions)
    const session = await host.start(manifestForLoad, { cwd: dirname(entry.path) })
    loaded.add(extensionId)
    loadedSessionIds.set(extensionId, session.id)
    log.withFields({ extensionId, sessionId: session.id }).log('extension loaded')
  }

  const stopLoadedExtensionById = async (extensionId: string) => {
    const sessionId = loadedSessionIds.get(extensionId)
    if (!sessionId) {
      loaded.delete(extensionId)
      return
    }

    await host.stop(sessionId)
    loadedSessionIds.delete(extensionId)

View on GitHub (pinned to 27111382b4)

Solutions

  1. Confirm the extension directory exists under the expected extensions root and contains a valid manifest file.
  2. Verify the extensionId string exactly matches the id declared in the extension's manifest.
  3. Trigger or await extension discovery/registry rebuild before attempting to load.
  4. Re-install or re-link the extension if it was removed during development.

Example fix

// before
await loadExtensionById('my-extension')

// after
const entry = extensionRegistry.findManifestEntry('my-extension')
if (!entry) {
  throw new Error(`Extension 'my-extension' not discovered. Check it is installed under the extensions root.`)
}
await loadExtensionById('my-extension')
Defensive patterns

Strategy: validation

Validate before calling

const entry = extensionRegistry.findManifestEntry(extensionId)
if (!entry) {
  throw new Error(`Cannot load '${extensionId}': not present in registry. Run discovery or install the extension.`)
}
await loadExtensionById(extensionId)

Type guard

function isKnownExtension(id: string, registry: { findManifestEntry: (id: string) => unknown }): boolean {
  return Boolean(registry.findManifestEntry(id))
}

Prevention

When it happens

Trigger: loadExtensionById is called with an extensionId that was not returned by discovery — because the extension folder is absent, the manifest file is missing/malformed, or the id is misspelled. Also occurs if discovery ran before the extension was installed.

Common situations: A plugin references an extensionId that doesn't exist; the extension directory was moved or deleted; the manifest's declared id doesn't match the id requested; discovery扫描 hasn't run yet at the time of the load call; a packaging step omitted the extension.

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/3312fe718392b25a. Report an issue: GitHub.