{"record":{"id":"bec8593c60ac87f4","repo":"TencentCloud/TencentDB-Agent-Memory","slug":"llm-provider-proxy-usememorysystemuserkey-false-bec859","errorCode":null,"errorMessage":"llm.provider=proxy 且 useMemorySystemUserKey=false 时必须显式配置 llm.apiKey","messagePattern":"llm\\.provider=proxy 且 useMemorySystemUserKey=false 时必须显式配置 llm\\.apiKey","errorType":"validation","errorClass":"LlmResolveError","httpStatus":null,"severity":"error","filePath":"MemoryCore/src/gateway/llm-resolver.ts","lineNumber":84,"sourceCode":"  const useSystemUserKey = llm.proxy?.useMemorySystemUserKey ?? true;\n  let effectiveApiKey = llm.apiKey;\n  if (useSystemUserKey) {\n    if (!memorySystemUser) {\n      throw new LlmResolveError(\n        \"llm.provider=proxy 且 llm.proxy.useMemorySystemUserKey=true 需要 \" +\n        \"metadata.systemUser.memory 完整配置（userId + userKey），当前缺失\",\n      );\n    }\n    if (!isValidMemorySystemUserKey(memorySystemUser.userKey)) {\n      throw new LlmResolveError(\n        \"metadata.systemUser.memory.userKey 必须匹配 sk-mem-[A-Za-z0-9_-]{32}\",\n      );\n    }\n    effectiveApiKey = memorySystemUser.userKey;\n  }\n\n  if (!effectiveApiKey) {\n    throw new LlmResolveError(\n      \"llm.provider=proxy 且 useMemorySystemUserKey=false 时必须显式配置 llm.apiKey\",\n    );\n  }\n\n  // baseUrl 拼接规则：去掉尾部斜杠，追加 /proxy/<iid>/v1\n  const cleanBase = llm.baseUrl.replace(/\\/+$/, \"\");\n  const proxyBaseUrl = `${cleanBase}/proxy/${encodeURIComponent(instanceId)}/v1`;\n\n  return {\n    ...llm,\n    baseUrl: proxyBaseUrl,\n    apiKey: effectiveApiKey,\n  };\n}\n\n/**\n * 只做校验、不返回配置 —— 用于启动期\"fail-fast\"检查。\n * standalone 模式下 instanceId 一般是 \"default\"，可以直接校验；","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/3efcd317b84146d6a08518ac0f7ee7c8a8d200ec/MemoryCore/src/gateway/llm-resolver.ts#L66-L102","documentation":"If proxy.useMemorySystemUserKey is false (opting out of memory system-user auth), the resolver requires llm.apiKey to be explicitly configured — effectiveApiKey ends up undefined otherwise, and this LlmResolveError is thrown. The proxy call must carry some credential, and this path demands a direct key.","triggerScenarios":"provider=proxy with llm.proxy.useMemorySystemUserKey: false and no llm.apiKey; also occurs when useMemorySystemUserKey=true but metadata.systemUser.memory is missing AND llm.apiKey is unset (effectiveApiKey still empty after the earlier throw path is bypassed by version differences).","commonSituations":"Operators disabling system-user auth assuming apiKey flows from elsewhere (env var never wired); migration from direct-provider mode where apiKey was removed along with the old provider config; typo in the apiKey field name.","solutions":["Set llm.apiKey explicitly in the yaml (or wire the env var into it) when useMemorySystemUserKey is false.","Remove useMemorySystemUserKey: false (or set true) and instead configure metadata.systemUser.memory if you intended system-user auth.","Double-check yaml indentation so apiKey sits under llm:, not a sibling block."],"exampleFix":"// before\nllm:\n  provider: proxy\n  baseUrl: http://127.0.0.1:8096\n  proxy:\n    useMemorySystemUserKey: false\n// after\nllm:\n  provider: proxy\n  baseUrl: http://127.0.0.1:8096\n  apiKey: sk-your-key\n  proxy:\n    useMemorySystemUserKey: false","handlingStrategy":"validation","validationCode":"if (llm.provider === 'proxy' && llm.proxy?.useMemorySystemUserKey === false && !llm.apiKey) {\n  throw new Error('useMemorySystemUserKey=false requires an explicit llm.apiKey');\n}","typeGuard":"function hasExplicitApiKey(llm: { provider: string; apiKey?: string; proxy?: { useMemorySystemUserKey?: boolean } }): boolean {\n  const useSysKey = llm.proxy?.useMemorySystemUserKey ?? true;\n  return llm.provider !== 'proxy' || useSysKey || (typeof llm.apiKey === 'string' && llm.apiKey.length > 0);\n}","tryCatchPattern":"try {\n  gateway.start();\n} catch (err) {\n  if (err instanceof LlmResolveError && err.message.includes('llm.apiKey')) {\n    console.error('Set llm.apiKey explicitly, or re-enable useMemorySystemUserKey with metadata.systemUser.memory configured');\n  }\n  throw err;\n}","preventionTips":["Whenever you opt out of system-user auth, supply llm.apiKey in the same config change","Wire API keys through secrets management, not hand-edited yaml","Keep auth strategy (system-user vs direct key) documented per environment","Run config validation before start() in deploy scripts"],"tags":["configuration","llm-proxy","api-key","authentication"],"backgroundTag":"missing-api-key","analyzedSha":"3efcd317b84146d6a08518ac0f7ee7c8a8d200ec","analyzedAt":"2026-09-01T05:44:22.276Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}