{"record":{"id":"32c3a61d91d4d85b","repo":"TencentCloud/TencentDB-Agent-Memory","slug":"memory-key-sk-mem-a-za-z0-9-32","errorCode":null,"errorMessage":"memory 系统用户 key 必须匹配 sk-mem-[A-Za-z0-9_-]{32}","messagePattern":"memory 系统用户 key 必须匹配 sk-mem-\\[A-Za-z0-9_-\\](.+?)","errorType":"error_code","errorClass":"LlmProviderResolveError","httpStatus":null,"severity":"error","filePath":"MemoryCore/src/adapters/standalone/llm-provider-resolver.ts","lineNumber":62,"sourceCode":"  }\n  if (!instanceId || !instanceId.trim()) {\n    throw new LlmProviderResolveError(\n      \"llm.provider=proxy 需要非空 instanceId，无法拼出 /proxy/<iid>/v1 路径\",\n    );\n  }\n\n  const useSystemUserKey = llm.proxy?.useMemorySystemUserKey ?? true;\n  let effectiveApiKey = llm.apiKey;\n  if (useSystemUserKey) {\n    const envKey = process.env.TDAI_MEMORY_SYSTEM_USER_KEY?.trim();\n    if (!envKey) {\n      throw new LlmProviderResolveError(\n        \"llm.provider=proxy 需要 memory 系统用户 key —— \" +\n        \"请在 yaml metadata.systemUser.memory 或 env TDAI_MEMORY_SYSTEM_USER_KEY 配置\",\n      );\n    }\n    if (!MEMORY_USER_KEY_RE.test(envKey)) {\n      throw new LlmProviderResolveError(\n        \"memory 系统用户 key 必须匹配 sk-mem-[A-Za-z0-9_-]{32}\",\n      );\n    }\n    effectiveApiKey = envKey;\n  }\n\n  if (!effectiveApiKey) {\n    throw new LlmProviderResolveError(\n      \"llm.provider=proxy 且 useMemorySystemUserKey=false 时必须显式 llm.apiKey\",\n    );\n  }\n\n  const cleanBase = llm.baseUrl.replace(/\\/+$/, \"\");\n  return {\n    ...llm,\n    baseUrl: `${cleanBase}/proxy/${encodeURIComponent(instanceId)}/v1`,\n    apiKey: effectiveApiKey,\n  };","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/3efcd317b84146d6a08518ac0f7ee7c8a8d200ec/MemoryCore/src/adapters/standalone/llm-provider-resolver.ts#L44-L80","documentation":"When TDAI_MEMORY_SYSTEM_USER_KEY is present in proxy mode, it must match the regex ^sk-mem-[A-Za-z0-9_-]{32}$ (sk-mem- prefix plus exactly 32 chars from [A-Za-z0-9_-]). This error is thrown when the key exists but is malformed, indicating a wrong value rather than a missing one.","triggerScenarios":"provider=\"proxy\", useMemorySystemUserKey true (default), TDAI_MEMORY_SYSTEM_USER_KEY set but not matching the sk-mem-[A-Za-z0-9_-]{32} pattern (wrong prefix, wrong length, invalid characters, surrounding whitespace already trimmed).","commonSituations":"Pasting an OpenAI-style sk-... key instead of a memory system user key; truncating or copy-paste truncating the key; using a JWT or other token format; quoting/newline issues when injecting via secret manager.","solutions":["Regenerate/copy the correct memory system user key (sk-mem- + 32 chars) and set it in TDAI_MEMORY_SYSTEM_USER_KEY","Validate the key locally: node -e 'console.log(/^sk-mem-[A-Za-z0-9_-]{32}$/.test(process.env.TDAI_MEMORY_SYSTEM_USER_KEY))'","Check for secret-manager injection issues (trailing newline stripped after trim, so look for truncation instead)","Alternatively bypass the check with useMemorySystemUserKey=false plus an explicit llm.apiKey"],"exampleFix":"// before\nTDAI_MEMORY_SYSTEM_USER_KEY=sk-proj-abc123\n// after\nTDAI_MEMORY_SYSTEM_USER_KEY=sk-mem-0123456789abcdef0123456789abcdef","handlingStrategy":"validation","validationCode":"const MEMORY_USER_KEY_RE = /^sk-mem-[A-Za-z0-9_-]{32}$/;\nfunction isValidMemoryUserKey(k) {\n  return typeof k === \"string\" && MEMORY_USER_KEY_RE.test(k);\n}","typeGuard":"function isMemoryUserKey(v) {\n  return typeof v === \"string\" && /^sk-mem-[A-Za-z0-9_-]{32}$/.test(v);\n}","tryCatchPattern":"try {\n  const runtimeLlm = resolveStandaloneLlmForRuntime(llm, instanceId);\n} catch (e) {\n  if (e instanceof LlmProviderResolveError && e.message.includes(\"sk-mem-\")) {\n    logger.error(\"TDAI_MEMORY_SYSTEM_USER_KEY has wrong format; expected sk-mem-<32 chars>\");\n  }\n  throw e;\n}","preventionTips":["Validate the key format right after loading it from the env/secret manager, before use","Never paste non-memory keys (sk-... OpenAI keys, JWTs) into TDAI_MEMORY_SYSTEM_USER_KEY","Watch for secret injection truncation; the format check catches most copy-paste corruption"],"tags":["validation","env-var","api-key","llm"],"backgroundTag":"invalid-api-key-format","analyzedSha":"3efcd317b84146d6a08518ac0f7ee7c8a8d200ec","analyzedAt":"2026-09-01T05:44:22.276Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}