diff --git a/openclaw/config.ts b/openclaw/config.ts index de1b86625..37dec0edf 100644 --- a/openclaw/config.ts +++ b/openclaw/config.ts @@ -196,14 +196,9 @@ export const mem0ConfigSchema = { const mode: Mem0Mode = cfg.mode === "oss" || cfg.mode === "open-source" ? "open-source" : "platform"; - // Platform mode requires apiKey - if (mode === "platform") { - if (typeof cfg.apiKey !== "string" || !cfg.apiKey) { - throw new Error( - "apiKey is required for platform mode (set mode: \"open-source\" for self-hosted)", - ); - } - } + // Platform mode requires apiKey — but don't throw on missing config. + // The plugin should register successfully and log a setup message. + const needsSetup = mode === "platform" && (typeof cfg.apiKey !== "string" || !cfg.apiKey); // Resolve env vars in oss config let ossConfig: Mem0Config["oss"]; @@ -241,6 +236,7 @@ export const mem0ConfigSchema = { searchThreshold: typeof cfg.searchThreshold === "number" ? cfg.searchThreshold : 0.5, topK: typeof cfg.topK === "number" ? cfg.topK : 5, + needsSetup, oss: ossConfig, skills: cfg.skills && typeof cfg.skills === "object" && !Array.isArray(cfg.skills) diff --git a/openclaw/index.ts b/openclaw/index.ts index 2900b92b0..1b3c38a97 100644 --- a/openclaw/index.ts +++ b/openclaw/index.ts @@ -94,6 +94,25 @@ const memoryPlugin = { register(api: OpenClawPluginApi) { const cfg = mem0ConfigSchema.parse(api.pluginConfig); + + // If API key is missing, register successfully but skip all memory operations. + // This prevents install from failing and gives the user a clear setup message. + if (cfg.needsSetup) { + api.logger.warn( + "openclaw-mem0: API key not configured. Memory features are disabled.\n" + + " To set up, run:\n" + + ' openclaw config set plugins.entries.openclaw-mem0.config.apiKey "m0-your-key"\n' + + " openclaw gateway restart\n" + + " Get your key at: https://app.mem0.ai/dashboard/api-keys" + ); + api.registerService({ + id: "openclaw-mem0", + start: () => { api.logger.info("openclaw-mem0: waiting for API key configuration"); }, + stop: () => {}, + }); + return; + } + const provider = createProvider(cfg, api); // Track current session ID for tool-level session scoping. diff --git a/openclaw/types.ts b/openclaw/types.ts index c94fd7641..62df25f6b 100644 --- a/openclaw/types.ts +++ b/openclaw/types.ts @@ -28,6 +28,8 @@ export type Mem0Config = { autoRecall: boolean; searchThreshold: number; topK: number; + // Setup state + needsSetup?: boolean; // Agentic harness skills skills?: SkillsConfig; };