{"record":{"id":"b18db5092f0fba96","repo":"TencentCloud/TencentDB-Agent-Memory","slug":"llm-provider-proxy-llm-baseurl-context-proxy-b18db5","errorCode":null,"errorMessage":"llm.provider=proxy 需要 llm.baseUrl 指向 context_proxy 根 URL","messagePattern":"llm\\.provider=proxy 需要 llm\\.baseUrl 指向 context_proxy 根 URL","errorType":"validation","errorClass":"LlmResolveError","httpStatus":null,"severity":"error","filePath":"MemoryCore/src/gateway/llm-resolver.ts","lineNumber":112,"sourceCode":"    ...llm,\n    baseUrl: proxyBaseUrl,\n    apiKey: effectiveApiKey,\n  };\n}\n\n/**\n * 只做校验、不返回配置 —— 用于启动期\"fail-fast\"检查。\n * standalone 模式下 instanceId 一般是 \"default\"，可以直接校验；\n * service 模式下 instanceId 每次请求才知道，启动期只校验 systemUser 是否合法。\n */\nexport function validateLlmProviderConfig(\n  llm: StandaloneLLMConfig,\n  metadata: GatewayMetadataConfig,\n): void {\n  if (llm.provider !== \"proxy\") return;\n\n  if (!llm.baseUrl) {\n    throw new LlmResolveError(\n      \"llm.provider=proxy 需要 llm.baseUrl 指向 context_proxy 根 URL\",\n    );\n  }\n\n  const useSystemUserKey = llm.proxy?.useMemorySystemUserKey ?? true;\n  if (useSystemUserKey) {\n    const memoryUser = resolveMemorySystemUserConfig(metadata);\n    if (!memoryUser) {\n      throw new LlmResolveError(\n        \"llm.provider=proxy 且 useMemorySystemUserKey=true 需要 \" +\n        \"metadata.systemUser.memory 完整配置（userId + userKey）\",\n      );\n    }\n    if (!isValidMemorySystemUserKey(memoryUser.userKey)) {\n      throw new LlmResolveError(\n        \"metadata.systemUser.memory.userKey 必须匹配 sk-mem-[A-Za-z0-9_-]{32}\",\n      );\n    }","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/3efcd317b84146d6a08518ac0f7ee7c8a8d200ec/MemoryCore/src/gateway/llm-resolver.ts#L94-L130","documentation":"validateLlmProviderConfig is a startup-time validator invoked by start(); it re-checks proxy requirements before the gateway accepts traffic. Like the runtime resolver, it requires llm.baseUrl when provider=proxy, throwing LlmResolveError at boot if absent.","triggerScenarios":"Starting the gateway (start()) with yaml llm.provider=proxy and no llm.baseUrl — the process fails fast before serving requests.","commonSituations":"First-time proxy setup with an incomplete yaml; config templating that dropped the baseUrl field; environment-specific overlays (staging/prod) that only override provider without carrying baseUrl over.","solutions":["Add llm.baseUrl pointing at the context_proxy root (e.g. http://127.0.0.1:8096) before starting.","Re-run start() after fixing; the same validation will then proceed to key/instance checks.","If proxy mode is unintentional, set llm.provider to the direct provider and supply its own baseUrl."],"exampleFix":"// before\nllm:\n  provider: proxy\n// after\nllm:\n  provider: proxy\n  baseUrl: http://127.0.0.1:8096","handlingStrategy":"validation","validationCode":"function preflightProxyConfig(llm) {\n  if (llm.provider === 'proxy' && !llm.baseUrl) {\n    throw new Error('Startup preflight: llm.provider=proxy requires llm.baseUrl (context_proxy root URL)');\n  }\n}","typeGuard":"function proxyConfigComplete(llm: { provider: string; baseUrl?: string }): boolean {\n  return llm.provider !== 'proxy' || Boolean(llm.baseUrl);\n}","tryCatchPattern":"try {\n  await gateway.start();\n} catch (err) {\n  if (err instanceof LlmResolveError && err.message.includes('context_proxy')) {\n    console.error('Add llm.baseUrl (context_proxy root, e.g. http://127.0.0.1:8096) before starting');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Run a startup preflight that mirrors validateLlmProviderConfig in CI","Keep proxy fields together in one config template/snippet to avoid omissions","Diff environment overlays against the base config for dropped keys","Start the gateway in staging after any provider/baseUrl change"],"tags":["configuration","startup","llm-proxy"],"backgroundTag":"missing-config-field","analyzedSha":"3efcd317b84146d6a08518ac0f7ee7c8a8d200ec","analyzedAt":"2026-09-01T05:44:22.276Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}