moeru-ai/airi · error · Error
Extension \` \` requires AIRI \` \`, but the running…
Error message
Extension \`${manifest.id}\` requires AIRI \`${manifest.engines.airi}\`, but the running version is \`${this.airiVersion}\`. What it means
When this.airiVersion is set, assertManifestCompatibility runs semver.satisfies(hostVersion, manifest.engines.airi, { includePrerelease: true }). If the running AIRI version does not satisfy the manifest's engines.airi range, the extension is refused. This protects extensions from being loaded by incompatible host versions.
Solutions
- Update manifest.engines.airi to a range that includes the running host version, then reinstall the extension.
- Upgrade the AIRI host to a version within the manifest's required range.
- Install a different extension release compatible with the current host.
- If the version is a prerelease, ensure the range is expressed correctly — includePrerelease is already enabled, so the range itself must include the version.
Example fix
// before
"engines": { "runtimes": ["electron"], "airi": "^0.9.0" } // host is 1.2.0
// after
"engines": { "runtimes": ["electron"], "airi": ">=0.9.0" } Defensive patterns
Strategy: validation
Validate before calling
import semver from 'semver'
const compatible = semver.satisfies(hostVersion, manifest.engines.airi, { includePrerelease: true })
if (!compatible) console.warn(`skip ${manifest.id}: requires airi ${manifest.engines.airi}`) Try / catch
try {
await host.start(extension)
} catch (e) {
if (/requires AIRI/.test(e.message)) promptHostUpgrade(e.message)
else throw e
} Prevention
- Use ranges (>= or ^) instead of exact pins in engines.airi unless strictly necessary.
- Bump engines.airi as part of the release checklist when breaking changes ship.
- Prefer installing extension versions built for your host version.
When it happens
Trigger: startExtension/start with a manifest whose engines.airi range excludes the current host version — e.g. host is 0.9.0 and manifest requires "^1.0.0".
Common situations: Upgrading or downgrading the AIRI host without updating extensions; an extension pinned to an old range; using a dev/nightly build against a manifest with an exact version pin; forgetting to bump engines.airi after a breaking release.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- AIRI version must be a valid semantic version
- Extension entrypoint id \
- Extension entrypoint is required for runtime \
- Extension \` \` does not support runtime \` \`.
- Extension \` \` does not support runtime \` \`.
AI-assisted analysis of moeru-ai/airi@438a067dde (2026-09-17).
Data as JSON: /api/errors/5603a0ec03c0b606.
Report an issue: GitHub.
Appendix: source
Thrown at packages/plugin-sdk/src/plugin-host/core.ts:247
throw new Error(`AIRI version must be a valid semantic version: ${options.airiVersion}`)
}
this.airiVersion = options.airiVersion
this.permissionResolver = options.permissionResolver
this.resources.setValue(protocolListProvidersEventName, [] as Array<{ name: string }>)
this.markCapabilityReady(protocolListProvidersEventName, { source: 'plugin-host' })
this.installContext = this.createInstallContext()
for (const contribution of options.contributions ?? []) {
this.installContribution(contribution)
}
}
private assertManifestCompatibility(manifest: ExtensionManifestV2, runtime: PluginRuntime) {
if (!manifest.engines.runtimes.includes(runtime)) {
throw new Error(`Extension \`${manifest.id}\` does not support runtime \`${runtime}\`.`)
}
if (this.airiVersion && !semver.satisfies(this.airiVersion, manifest.engines.airi, { includePrerelease: true })) {
throw new Error(
`Extension \`${manifest.id}\` requires AIRI \`${manifest.engines.airi}\`, but the running version is \`${this.airiVersion}\`.`,
)
}
}
async startExtension(
extension: Extension,
options: { manifest: ExtensionManifestV2, cwd?: string, runtime?: PluginRuntime },
) {
const runtime = options.runtime ?? this.runtime
this.assertManifestCompatibility(options.manifest, runtime)
if (extension.id !== options.manifest.id) {
throw new Error(`Extension entrypoint id \`${extension.id}\` must match manifest id \`${options.manifest.id}\`.`)
}
const sessionIdentity = this.extensionSessionService.nextSessionIdentity()
const extensionIdentity = {View on GitHub (pinned to 438a067dde)