can1357/oh-my-pi · error · TypeError

Plugin must implement onRemember

Error message

Plugin must implement onRemember

What it means

MnemopiPlugin's onRemember is a stub hook that throws this TypeError when a subclass fails to override it. The base class deliberately provides throwing defaults instead of abstract TypeScript methods so JavaScript consumers also fail loudly; the plugin host calls onRemember for every stored memory.

Source

Thrown at packages/mnemopi/src/core/plugins.ts:37

		if (new.target === MnemopiPlugin) throw new TypeError("MnemopiPlugin is abstract");
		this.config = config;
		const ctor = this.constructor as typeof MnemopiPlugin;
		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

  1. Override onRemember(memory: MemoryDict): void in your plugin subclass
  2. If the hook is irrelevant to your plugin, provide an empty override body
  3. Verify the deployed plugin file is the version you edited (stale builds often miss new overrides)

Example fix

// before
class MyPlugin extends MnemopiPlugin { override onRecall(m: MemoryDict): void {} }
// after
class MyPlugin extends MnemopiPlugin { override onRecall(m: MemoryDict): void {} override onRemember(m: MemoryDict): void { /* ... */ } }
Defensive patterns

Strategy: type-guard

Validate before calling

function implementsOnRemember(p: MnemopiPlugin): boolean {
  return p.onRemember !== MnemopiPlugin.prototype.onRemember;
}
// before registering:
if (!implementsOnRemember(plugin)) throw new Error(`plugin ${plugin.name} must override onRemember`);

Type guard

function overridesOnRemember<P extends MnemopiPlugin>(p: P): p is P & { onRemember(m: MemoryDict): void } {
  return p.onRemember !== MnemopiPlugin.prototype.onRemember;
}

Try / catch

try {
  host.remember(memory);
} catch (err) {
  if (err instanceof TypeError && err.message === "Plugin must implement onRemember") {
    logger.error(`plugin ${plugin.name} is missing an onRemember override; skipping it`, { plugin: plugin.toDict() });
  } else throw err;
}

Prevention

When it happens

Trigger: Registering a plugin subclass that overrides some hooks (or none) but not onRemember, then storing/remembering a memory so the host invokes plugin.onRemember(memory).

Common situations: A third-party plugin updated against a changed hook API; a custom plugin where onRemember was renamed or deleted during refactoring; calling the base method via super.onRemember() intentionally or by omission of the override.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/3188df560bf4bd47. Report an issue: GitHub.