{"record":{"id":"c3882ce61bc3c14d","repo":"linshenkx/prompt-optimizer","slug":"text2image-input-image-not-allowed","errorCode":"TEXT2IMAGE_INPUT_IMAGE_NOT_ALLOWED","errorMessage":"TEXT2IMAGE_INPUT_IMAGE_NOT_ALLOWED","messagePattern":"TEXT2IMAGE_INPUT_IMAGE_NOT_ALLOWED","errorType":"validation","errorClass":"ImageError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/image/service.ts","lineNumber":81,"sourceCode":"    // 兼容入口：仍按是否携带 inputImage 判断模式。\n    // 注意：这是 legacy 行为；推荐调用方使用显式的 validateText2ImageRequest/validateImage2ImageRequest。\n    if (request.inputImage) {\n      const image2image: Image2ImageRequest = { ...request, inputImage: request.inputImage }\n      await this.validateImage2ImageRequest(image2image)\n      return\n    }\n\n    const { inputImage: _inputImage, ...rest } = request\n    const text2image: Text2ImageRequest = rest\n    await this.validateText2ImageRequest(text2image)\n  }\n\n  async validateText2ImageRequest(request: Text2ImageRequest): Promise<void> {\n    // 显式文生图：不允许携带 inputImage（即使调用方用 any 绕过类型）\n    const unsafeInputImage = (request as unknown as { inputImage?: unknown }).inputImage\n    const unsafeInputImages = (request as unknown as { inputImages?: unknown }).inputImages\n    if (unsafeInputImage !== undefined && unsafeInputImage !== null) {\n      throw new ImageError(IMAGE_ERROR_CODES.TEXT2IMAGE_INPUT_IMAGE_NOT_ALLOWED)\n    }\n    if (Array.isArray(unsafeInputImages) && unsafeInputImages.length > 0) {\n      throw new ImageError(IMAGE_ERROR_CODES.TEXT2IMAGE_INPUT_IMAGE_NOT_ALLOWED)\n    }\n\n    await this.validateBaseRequest(request)\n\n    const config = await this.imageModelManager.getConfig(request.configId)\n    if (!config) {\n      throw new ImageError(IMAGE_ERROR_CODES.CONFIG_NOT_FOUND, undefined, { configId: request.configId })\n    }\n\n    // 能力校验：优先使用 config.model（动态/自定义模型），静态列表作为兜底\n    const configModel = config.model\n    const staticModels = this.registry.getStaticModels(config.providerId)\n    const staticModel = staticModels.find(m => m.id === config.modelId)\n    const capabilities = configModel?.capabilities ?? staticModel?.capabilities\n    const modelName = configModel?.name ?? staticModel?.name ?? config.modelId","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/image/service.ts#L63-L99","documentation":"An explicit text-to-image request must not carry input images. validateText2ImageRequest inspects even untyped `inputImage` fields (cast through any) and throws TEXT2IMAGE_INPUT_IMAGE_NOT_ALLOWED when a single input image is present on a text2image call.","triggerScenarios":"Calling generateText2Image or validateRequest with a request object that includes a non-null `inputImage` property — typically because a form/UI reused an image2image request object, or a caller added inputImage via any-typed spread.","commonSituations":"UI mode toggle between img2img and t2i not stripping inputImage from the shared request state; deserializing a saved request of the wrong type; API consumers sending a 'kitchen sink' payload.","solutions":["Delete inputImage before sending: const { inputImage, ...rest } = request; generateText2Image(rest)","Fix the UI to reset input image state when switching to text2image mode","Use generateImage2Image when you actually want image conditioning"],"exampleFix":"// before\nawait service.generateText2Image({ ...formState } as any) // formState still has inputImage\n\n// after\nconst { inputImage, inputImages, ...t2i } = formState\nawait service.generateText2Image(t2i)","handlingStrategy":"validation","validationCode":"function toStrictT2I<T extends Record<string, any>>(req: T): Omit<T, 'inputImage' | 'inputImages'> {\n  const { inputImage, inputImages, ...rest } = req\n  return rest\n}\n// usage: await service.generateText2Image(toStrictT2I(formState) as Text2ImageRequest)","typeGuard":"function isPureText2ImageRequest(r: unknown): boolean {\n  const o = r as any\n  return (o?.inputImage === undefined || o?.inputImage === null) &&\n    !(Array.isArray(o?.inputImages) && o.inputImages.length > 0)\n}","tryCatchPattern":"try {\n  await service.generateText2Image(req as Text2ImageRequest)\n} catch (e) {\n  if (e instanceof ImageError && e.code === IMAGE_ERROR_CODES.TEXT2IMAGE_INPUT_IMAGE_NOT_ALLOWED) {\n    const { inputImage, inputImages, ...clean } = req as any\n    return service.generateText2Image(clean)\n  }\n  throw e\n}","preventionTips":["Build t2i and i2i request objects in separate code paths instead of sharing mutable state","Reset input image fields on mode switch in the UI"],"tags":["validation","text2image","request-payload","image-generation"],"backgroundTag":"request-validation-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}