{"record":{"id":"3188df560bf4bd47","repo":"can1357/oh-my-pi","slug":"plugin-must-implement-onremember","errorCode":null,"errorMessage":"Plugin must implement onRemember","messagePattern":"Plugin must implement onRemember","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/mnemopi/src/core/plugins.ts","lineNumber":37,"sourceCode":"\t\tif (new.target === MnemopiPlugin) throw new TypeError(\"MnemopiPlugin is abstract\");\n\t\tthis.config = config;\n\t\tconst ctor = this.constructor as typeof MnemopiPlugin;\n\t\tthis.name =\n\t\t\t(ctor.prototype.name as string | undefined) ?? (ctor as unknown as { name?: string }).name ?? this.name;\n\t\tthis.version = (ctor.prototype.version as string | undefined) ?? this.version;\n\t\tthis.enabled = (ctor.prototype.enabled as boolean | undefined) ?? this.enabled;\n\t}\n\n\tinitialize(): void {\n\t\tthis.initialized = true;\n\t}\n\n\tshutdown(): void {\n\t\tthis.initialized = false;\n\t}\n\n\tonRemember(_memory: MemoryDict): void {\n\t\tthrow new TypeError(\"Plugin must implement onRemember\");\n\t}\n\tonRecall(_memory: MemoryDict): void {\n\t\tthrow new TypeError(\"Plugin must implement onRecall\");\n\t}\n\tonConsolidate(_summary: MemoryDict): void {\n\t\tthrow new TypeError(\"Plugin must implement onConsolidate\");\n\t}\n\tonInvalidate(_memoryId: string): void {\n\t\tthrow new TypeError(\"Plugin must implement onInvalidate\");\n\t}\n\ttoDict(): Record<string, unknown> {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tversion: this.version,\n\t\t\tenabled: this.enabled,\n\t\t\tinitialized: this.initialized,\n\t\t\tconfig: this.config,\n\t\t};","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/mnemopi/src/core/plugins.ts#L19-L55","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Override onRemember(memory: MemoryDict): void in your plugin subclass","If the hook is irrelevant to your plugin, provide an empty override body","Verify the deployed plugin file is the version you edited (stale builds often miss new overrides)"],"exampleFix":"// before\nclass MyPlugin extends MnemopiPlugin { override onRecall(m: MemoryDict): void {} }\n// after\nclass MyPlugin extends MnemopiPlugin { override onRecall(m: MemoryDict): void {} override onRemember(m: MemoryDict): void { /* ... */ } }","handlingStrategy":"type-guard","validationCode":"function implementsOnRemember(p: MnemopiPlugin): boolean {\n  return p.onRemember !== MnemopiPlugin.prototype.onRemember;\n}\n// before registering:\nif (!implementsOnRemember(plugin)) throw new Error(`plugin ${plugin.name} must override onRemember`);","typeGuard":"function overridesOnRemember<P extends MnemopiPlugin>(p: P): p is P & { onRemember(m: MemoryDict): void } {\n  return p.onRemember !== MnemopiPlugin.prototype.onRemember;\n}","tryCatchPattern":"try {\n  host.remember(memory);\n} catch (err) {\n  if (err instanceof TypeError && err.message === \"Plugin must implement onRemember\") {\n    logger.error(`plugin ${plugin.name} is missing an onRemember override; skipping it`, { plugin: plugin.toDict() });\n  } else throw err;\n}","preventionTips":["Implement all four hooks (onRemember/onRecall/onConsolidate/onInvalidate) in every plugin, even as no-ops","Use TypeScript `override` keyword so missing/renamed overrides are compile errors","Keep plugin classes in a template/scaffold that includes all hooks","Test each plugin against the host before deployment"],"tags":["typescript","plugins","unimplemented-method"],"backgroundTag":"unimplemented-hook-method","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}