{"record":{"id":"8d2cdbf576a61051","repo":"linshenkx/prompt-optimizer","slug":"api-key-required","errorCode":"API_KEY_REQUIRED","errorMessage":"API_KEY_REQUIRED","messagePattern":"API_KEY_REQUIRED","errorType":"validation","errorClass":"ImageError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/image/adapters/siliconflow.ts","lineNumber":242,"sourceCode":"            image2image: true,\n            multiImage: false\n          },\n          parameterDefinitions: this.getParameterDefinitions(model.id),\n          defaultParameterValues: this.getDefaultParameterValues(model.id)\n        })\n      }\n    })\n\n    return Array.from(allModelsMap.values())\n  }\n\n  protected validateConnectionConfig(connectionConfig: Record<string, any>): void {\n    // 基础验证\n    super.validateConnectionConfig(connectionConfig)\n\n    // SiliconFlow 特定验证\n    if (!connectionConfig.apiKey) {\n      throw new ImageError(IMAGE_ERROR_CODES.API_KEY_REQUIRED, undefined, { providerName: 'SiliconFlow' })\n    }\n  }\n\n  protected getTestImageRequest(testType: 'text2image' | 'image2image'): Omit<ImageRequest, 'configId'> {\n    if (testType === 'text2image') {\n      return {\n        prompt: 'a flower',\n        count: 1\n      }\n    }\n\n    if (testType === 'image2image') {\n      return {\n        prompt: 'make it red',\n        count: 1,\n        inputImage: {\n          b64: AbstractImageProviderAdapter.TEST_IMAGE_BASE64.split(',')[1], // 去掉data:前缀\n          mimeType: 'image/png'","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/image/adapters/siliconflow.ts#L224-L260","documentation":"The SiliconFlow adapter requires an `apiKey` in its connection config. After the base adapter validation passes, the SiliconFlow-specific check throws API_KEY_REQUIRED when `connectionConfig.apiKey` is falsy.","triggerScenarios":"Calling validateConnectionConfig (directly or via getModelsAsync / connection save flow) with a connectionConfig that is missing apiKey, sets it to empty string, or passes undefined because the key was never prompted for.","commonSituations":"User creates a SiliconFlow image connection but leaves the API key field blank; the key is stored under a different config key name; env-var-based key injection not set in CI; UI silently dropping the apiKey field on edit.","solutions":["Add a valid SiliconFlow API key to the connection config: { apiKey: 'sk-...' }","Verify the config key is spelled exactly 'apiKey' (case-sensitive)","Confirm the settings UI actually persists the key before triggering validation","Generate a key at SiliconFlow dashboard if you don't have one"],"exampleFix":"// before\nawait adapter.validateConnectionConfig({ baseUrl: 'https://api.siliconflow.cn' })\n\n// after\nawait adapter.validateConnectionConfig({\n  baseUrl: 'https://api.siliconflow.cn',\n  apiKey: process.env.SILICONFLOW_API_KEY\n})","handlingStrategy":"validation","validationCode":"if (!connectionConfig?.apiKey || typeof connectionConfig.apiKey !== 'string') {\n  throw new Error('SiliconFlow connection requires connectionConfig.apiKey')\n}\nawait adapter.validateConnectionConfig(connectionConfig)","typeGuard":"function hasSiliconFlowConfig(c: unknown): c is { apiKey: string; baseUrl?: string } {\n  return typeof c === 'object' && c !== null && typeof (c as any).apiKey === 'string' && (c as any).apiKey.length > 0\n}","tryCatchPattern":"try {\n  await adapter.validateConnectionConfig(cfg)\n} catch (e) {\n  if (e instanceof ImageError && e.code === IMAGE_ERROR_CODES.API_KEY_REQUIRED) {\n    promptUserForApiKey(); return\n  }\n  throw e\n}","preventionTips":["Mark apiKey as required in connection form schemas","Validate config shape before save, not only before API calls","Never commit configs; inject keys from env/secret store at runtime"],"tags":["siliconflow","api-key","connection-config","validation"],"backgroundTag":"missing-api-key","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}