{"record":{"id":"87c3a8587fe33240","repo":"toeverything/AFFiNE","slug":"action-bridge-stream-error","errorCode":"action_bridge_stream_error","errorMessage":"Action image generation produced no image","messagePattern":"Action image generation produced no image","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/backend/server/src/plugins/copilot/runtime/action-runtime-bridge.ts","lineNumber":131,"sourceCode":"        step.slot\n      );\n      return { result: output.value, attachments: [] };\n    }\n    const images = [];\n    for await (const image of this.runtime.streamImageArtifacts(\n      { profileId: step.profileId, modelId: step.modelId },\n      step.messages,\n      {\n        ...(step.options as CopilotImageOptions | undefined),\n        builtInRouteId: step.builtInRouteId,\n      },\n      undefined,\n      step.slot\n    )) {\n      images.push(image);\n    }\n    const result = images[0];\n    if (!result) throw new Error('Action image generation produced no image');\n    return { result, attachments: [result] };\n  }\n\n  private async projectAssistantResult(\n    input: ActionRuntimeBridgeInput,\n    result: unknown,\n    artifacts: unknown[],\n    wasAborted: boolean\n  ) {\n    if (!input.session) return null;\n    const turn = projectActionResultToAssistantTurn({\n      session: input.session,\n      actionId: input.actionId,\n      result,\n      artifacts,\n      wasAborted,\n    });\n    if (!turn) return null;","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/backend/server/src/plugins/copilot/runtime/action-runtime-bridge.ts#L113-L149","documentation":"During an AI action, the bridge streams the configured image model and collects yielded images; if the stream completes without producing any image it throws Error('Action image generation produced no image'), surfaced under code `action_bridge_stream_error`. The provider round-trip finished but returned zero images.","triggerScenarios":"The image model returns empty content: safety/moderation refusal, provider hiccup, a route/model that is not actually image-capable for the request shape, or options causing the model to emit nothing for the slot.","commonSituations":"Switching the image route to a model without real image output; prompts that trip provider content filters; free-tier providers intermittently returning empty completions; misconfigured builtInRouteId resolving to a text model.","solutions":["Retry the action — transient empty generations from image providers are common","Confirm the selected model/route actually supports image generation (check model capabilities and builtInRouteId)","Adjust the image prompt to avoid content likely filtered by provider moderation","Check the provider dashboard/logs for refused or empty completions at that timestamp"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// guard: confirm the route/model is image-capable before running the action\nconst caps = await fetchModelCapabilities(step.modelId);\nif (!caps.includes('image_generation')) {\n  throw new Error('selected model cannot generate images — pick an image route');\n}","typeGuard":"function isActionStreamError(e: unknown): boolean {\n  return (e as { extensions?: { code?: string } })?.extensions?.code === 'action_bridge_stream_error' ||\n    /produced no image/.test((e as Error)?.message ?? '');\n}","tryCatchPattern":"try {\n  return await runImageAction(step);\n} catch (e) {\n  if (isActionStreamError(e)) {\n    await sleep(1000);\n    return runImageAction(step); // empty generations are often transient\n  }\n  throw e;\n}","preventionTips":["Pin image actions to routes verified to support image output","Keep image prompts clear of content likely to hit provider moderation","Cap retries (1-2) and fall back to a user-visible 'try again' state"],"tags":["copilot","action","image-generation","ai-provider","streaming"],"backgroundTag":"ai-provider-empty-response","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}