{"record":{"id":"100a8c2c0806c272","repo":"TencentCloud/TencentDB-Agent-Memory","slug":"embeddingservice-apikey-is-required-for-remote-pr","errorCode":null,"errorMessage":"EmbeddingService: apiKey is required for remote provider","messagePattern":"EmbeddingService: apiKey is required for remote provider","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"MemoryCore/src/core/store/embedding.ts","lineNumber":416,"sourceCode":"    total_tokens: number;\n  };\n}\n\nexport class OpenAIEmbeddingService implements EmbeddingService {\n  private readonly baseUrl: string;\n  private readonly apiKey: string;\n  private readonly model: string;\n  private readonly dims: number;\n  private readonly sendDimensions: boolean;\n  private readonly providerName: string;\n  private readonly proxyUrl?: string;\n  private readonly maxInputChars?: number;\n  private readonly timeoutMs: number;\n  private readonly logger?: Logger;\n\n  constructor(config: OpenAIEmbeddingConfig, logger?: Logger) {\n    if (!config.apiKey) {\n      throw new Error(\"EmbeddingService: apiKey is required for remote provider\");\n    }\n    if (!config.baseUrl) {\n      throw new Error(\"EmbeddingService: baseUrl is required for remote provider\");\n    }\n    if (!config.model) {\n      throw new Error(\"EmbeddingService: model is required for remote provider\");\n    }\n    if (!config.dimensions || config.dimensions <= 0) {\n      throw new Error(\"EmbeddingService: dimensions is required for remote provider (must be a positive integer)\");\n    }\n    this.baseUrl = config.baseUrl.replace(/\\/+$/, \"\");\n    this.apiKey = config.apiKey;\n    this.model = config.model;\n    this.dims = config.dimensions;\n    this.sendDimensions = config.sendDimensions ?? true;\n    this.providerName = config.provider || \"openai\";\n    this.proxyUrl = config.proxyUrl?.trim() || undefined;\n    this.maxInputChars = config.maxInputChars && config.maxInputChars > 0 ? config.maxInputChars : undefined;","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/3efcd317b84146d6a08518ac0f7ee7c8a8d200ec/MemoryCore/src/core/store/embedding.ts#L398-L434","documentation":"The OpenAI-compatible remote EmbeddingService constructor validates its config before doing any work. An embedding client without an API key can never authenticate, so the constructor fails fast with this error instead of producing confusing HTTP 401s later. It is thrown only when the provider is remote (OpenAI-compatible) and config.apiKey is falsy.","triggerScenarios":"Calling `new EmbeddingService(config)` (OpenAI-compatible remote provider) where config.apiKey is undefined, null, or an empty/whitespace string.","commonSituations":"Environment variable not loaded (e.g. OPENAI_API_KEY unset or .env not read before constructing), config object read from a JSON file where the apiKey field was renamed or omitted, or accidentally using the remote constructor for a local provider without supplying a key.","solutions":["Set config.apiKey to a valid key for the remote provider before constructing EmbeddingService","Load the key from the environment (process.env.OPENAI_API_KEY) and check it is non-empty before construction","If embeddings are meant to be local, switch to the local provider config instead of OpenAIEmbeddingConfig"],"exampleFix":"// before\nnew EmbeddingService({ baseUrl: 'https://api.openai.com/v1', model: 'text-embedding-3-small', dimensions: 1536 })\n// after\nif (!process.env.OPENAI_API_KEY) throw new Error('OPENAI_API_KEY missing');\nnew EmbeddingService({ apiKey: process.env.OPENAI_API_KEY, baseUrl: 'https://api.openai.com/v1', model: 'text-embedding-3-small', dimensions: 1536 })","handlingStrategy":"validation","validationCode":"function assertEmbeddingConfig(cfg) {\n  if (!cfg?.apiKey || !cfg.apiKey.trim()) throw new Error('apiKey is required');\n  return cfg;\n}\nassertEmbeddingConfig(config);","typeGuard":"function hasApiKey(cfg): cfg is Required<Pick<OpenAIEmbeddingConfig,'apiKey'>> & OpenAIEmbeddingConfig {\n  return typeof cfg?.apiKey === 'string' && cfg.apiKey.trim().length > 0;\n}","tryCatchPattern":"try {\n  svc = new EmbeddingService(config, logger);\n} catch (e) {\n  if (String(e.message).includes('apiKey is required')) {\n    throw new ConfigError('OPENAI_API_KEY not set; check env/config loading');\n  }\n  throw e;\n}","preventionTips":["Fail fast at process startup: assert required env vars before constructing services","Load .env/config before importing/constructing the embedding client","Add a unit test constructing the service with the real config loader"],"tags":["configuration","constructor","embedding","missing-credential"],"backgroundTag":"missing-api-key","analyzedSha":"3efcd317b84146d6a08518ac0f7ee7c8a8d200ec","analyzedAt":"2026-09-01T05:44:22.276Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}