{"record":{"id":"a7c58c141a954f3d","repo":"mem0ai/mem0","slug":"label-has-unknown-keys-unknown-join","errorCode":null,"errorMessage":"${label} has unknown keys: ${unknown.join(\", \")}","messagePattern":"(.+?) has unknown keys: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"integrations/openclaw/config.ts","lineNumber":172,"sourceCode":"  \"autoCapture\",\n  \"autoRecall\",\n  \"customInstructions\",\n  \"customCategories\",\n  \"customPrompt\",\n  \"searchThreshold\",\n  \"topK\",\n  \"oss\",\n  \"skills\",\n];\n\nfunction assertAllowedKeys(\n  value: Record<string, unknown>,\n  allowed: string[],\n  label: string,\n) {\n  const unknown = Object.keys(value).filter((key) => !allowed.includes(key));\n  if (unknown.length === 0) return;\n  throw new Error(`${label} has unknown keys: ${unknown.join(\", \")}`);\n}\n\nexport const mem0ConfigSchema = {\n  parse(value: unknown, fileConfig?: FileConfig): Mem0Config {\n    if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n      throw new Error(\"openclaw-mem0 config required\");\n    }\n    const cfg = value as Record<string, unknown>;\n    assertAllowedKeys(cfg, ALLOWED_KEYS, \"openclaw-mem0 config\");\n\n    // Only two modes: \"platform\" (default) or \"open-source\"\n    if (\n      typeof cfg.mode === \"string\" &&\n      cfg.mode !== \"platform\" &&\n      cfg.mode !== \"open-source\"\n    ) {\n      console.warn(\n        `[mem0] Unknown mode \"${cfg.mode}\" — expected \"platform\" or \"open-source\". Defaulting to \"platform\".`,","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/integrations/openclaw/config.ts#L154-L190","documentation":"Strict-schema error thrown by mem0ConfigSchema.parse (via assertAllowedKeys) when the openclaw-mem0 plugin config in openclaw.json contains keys outside ALLOWED_KEYS (mode, apiKey, anonymousTelemetryId, baseUrl, userId, userEmail, autoCapture, autoRecall, customInstructions, customCategories, customPrompt, searchThreshold, topK, oss, skills). The message lists every offending key. Unknown mode values get a warning instead — but unknown keys hard-fail.","triggerScenarios":"Adding a top-level key to the plugins['openclaw-mem0'] section that is not in ALLOWED_KEYS, e.g. 'llm', 'embedder', 'version', or a misspelled key like 'apikey' (keys are case-sensitive).","commonSituations":"Copy-pasting config snippets from docs of a different plugin version; renaming of accepted keys between versions; users putting OSS sub-settings at top level instead of inside the 'oss' object.","solutions":["Remove or rename the listed unknown keys so only ALLOWED_KEYS remain at the top level of the plugin section.","OSS provider settings (llm, embedder, vectorStore) belong inside the 'oss' object, not at top level — move them there.","Check key casing: apiKey not apikey, searchThreshold not search_threshold."],"exampleFix":"// before (openclaw.json)\n\"openclaw-mem0\": { \"mode\": \"open-source\", \"apikey\": \"m0-...\" }\n\n// after\n\"openclaw-mem0\": { \"mode\": \"open-source\", \"apiKey\": \"m0-...\" }","handlingStrategy":"validation","validationCode":"const ALLOWED = ['mode','apiKey','anonymousTelemetryId','baseUrl','userId','userEmail','autoCapture','autoRecall','customInstructions','customCategories','customPrompt','searchThreshold','topK','oss','skills'];\nconst unknown = Object.keys(pluginCfg).filter((k) => !ALLOWED.includes(k));\nif (unknown.length) throw new Error(`unknown config keys: ${unknown.join(', ')}`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep OSS provider settings nested under the 'oss' key.","Match key casing exactly (apiKey, searchThreshold, topK).","Re-validate config after copying snippets from docs — versions drift."],"tags":["config","schema","validation","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}