can1357/oh-my-pi · error · TypeError
Plugin must implement onRecall
Error message
Plugin must implement onRecall
What it means
MnemopiPlugin's onRecall is a throwing stub: subclasses must override it because the plugin host invokes it on every memory recall. Hitting this TypeError means the registered plugin never implemented the recall hook.
Source
Thrown at packages/mnemopi/src/core/plugins.ts:40
this.name =
(ctor.prototype.name as string | undefined) ?? (ctor as unknown as { name?: string }).name ?? this.name;
this.version = (ctor.prototype.version as string | undefined) ?? this.version;
this.enabled = (ctor.prototype.enabled as boolean | undefined) ?? this.enabled;
}
initialize(): void {
this.initialized = true;
}
shutdown(): void {
this.initialized = false;
}
onRemember(_memory: MemoryDict): void {
throw new TypeError("Plugin must implement onRemember");
}
onRecall(_memory: MemoryDict): void {
throw new TypeError("Plugin must implement onRecall");
}
onConsolidate(_summary: MemoryDict): void {
throw new TypeError("Plugin must implement onConsolidate");
}
onInvalidate(_memoryId: string): void {
throw new TypeError("Plugin must implement onInvalidate");
}
toDict(): Record<string, unknown> {
return {
name: this.name,
version: this.version,
enabled: this.enabled,
initialized: this.initialized,
config: this.config,
};
}
}
View on GitHub (pinned to 9690622007)
Solutions
- Override onRecall(memory: MemoryDict): void in the plugin subclass
- Provide a no-op override if recall events are irrelevant
- Rebuild/redeploy the plugin so the override is actually present at runtime
Example fix
// before
class MyPlugin extends MnemopiPlugin { override onRemember(m: MemoryDict): void {} }
// after
class MyPlugin extends MnemopiPlugin { override onRemember(m: MemoryDict): void {} override onRecall(m: MemoryDict): void { /* ... */ } } Defensive patterns
Strategy: type-guard
Validate before calling
function implementsOnRecall(p: MnemopiPlugin): boolean {
return p.onRecall !== MnemopiPlugin.prototype.onRecall;
}
if (!implementsOnRecall(plugin)) throw new Error(`plugin ${plugin.name} must override onRecall`); Type guard
function overridesOnRecall<P extends MnemopiPlugin>(p: P): p is P & { onRecall(m: MemoryDict): void } {
return p.onRecall !== MnemopiPlugin.prototype.onRecall;
} Try / catch
try {
host.recall(id);
} catch (err) {
if (err instanceof TypeError && err.message === "Plugin must implement onRecall") {
logger.error(`plugin ${plugin.name} lacks onRecall; unregistering it`);
host.unregister(plugin);
} else throw err;
} Prevention
- Scaffold new plugins from a template containing all hook stubs
- Use `override` keyword and strict TypeScript checks to catch renamed methods
- Run a plugin conformance test comparing each hook against MnemopiPlugin.prototype
- Rebuild plugins after upgrades in case hook signatures changed
When it happens
Trigger: A plugin subclass registered with the host that does not override onRecall, triggered when a memory is recalled and the host iterates plugins calling plugin.onRecall(memory).
Common situations: Writing a plugin that only cares about onRemember/onConsolidate; a refactor renaming the method so the override no longer matches; loading a stale or minified plugin build without the override.
Related errors
- Plugin must implement onRemember
- Plugin must implement onConsolidate
- Plugin must implement onInvalidate
- MnemopiPlugin is abstract
- Destination option ${key} must be a string
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/f442edb5e35386e3.
Report an issue: GitHub.