Skip to content

image_generate duplicate guard drops distinct second image requests in one session #83610

@Elarwei001

Description

@Elarwei001

Summary

When an agent needs to generate multiple different images for the same user request, the current image_generate duplicate guard can cause later image requests to be silently treated as status checks for the first active task. The later image is not queued or started, but the tool response can make the agent believe work is still in progress.

This is not about duplicate retries for the same image. It affects multi-image / multi-prompt workflows where each image has a distinct prompt and output filename.

Observed behavior

A session asked an agent to create two different educational diagrams in one workflow:

  1. Generate diagram A.
  2. Generate diagram B with a different prompt and filename.
  3. Send both images and embed them in the document.

The first image_generate call started a background task as expected.

The second image_generate call happened while the first task was still active. Instead of starting or queueing the second task, the tool returned the active task status for the first task:

  • action: "status"
  • duplicateGuard: true
  • existingTask: true
  • task.taskId for the first image task

No new task was created for the second image, and the second image's prompt/filename were not recorded in the task ledger. The agent then reported that both images were being generated, even though only the first one was actually running.

Why this seems like a bug

The duplicate guard is session-scoped. It checks whether there is any active image generation task for the session before parsing/recording the new prompt and filename. That means it cannot distinguish:

  • a retry/duplicate call for the same image request, from
  • a valid second image request in the same user workflow.

For a same-request retry, returning active status is reasonable. For a different image request, the current behavior drops the new request.

Expected behavior

OpenClaw should either:

  1. queue distinct image generation requests within the same session, preserving each request's prompt, filename, model/options, and requester context; or
  2. explicitly reject the new request with a clear structured result, for example newTaskStarted: false and rejectedReason: "active_task_exists", and text that says this call did not start a new generation task.

The current status-like response is ambiguous for agents and can lead to false progress reports.

Reproduction sketch

  1. In a session-backed chat, ask the agent to generate two different images with different prompts/filenames.
  2. Have the agent call image_generate for image A.
  3. Before image A completes, have the agent call image_generate for image B.
  4. Observe that only image A gets a background task. The image B call returns the active image A task status instead of starting or queueing image B.

No private image IDs, user content, or exact prompts are needed to reproduce this. Any two distinct prompts should work.

Relevant code paths

  • src/agents/tools/image-generate-tool.ts
  • src/agents/tools/image-generate-tool.actions.ts
  • src/agents/tools/media-generate-tool-actions-shared.ts
  • src/agents/image-generation-task-status.ts
  • src/agents/session-async-task-status.ts
  • src/agents/tools/media-generate-background-shared.ts

The duplicate guard currently runs before the new request is represented as a task, and active task lookup is scoped to session/task kind rather than request identity.

Fix work

I am preparing a PR that explores a fuller fix for multi-image workflows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions