Skip to content

fix(task-create): handle WorkflowAlreadyStartedError gracefully - #489

Merged
alvinkam2001 merged 2 commits into
nextfrom
akam/task-create-idempotency
Aug 7, 2026
Merged

fix(task-create): handle WorkflowAlreadyStartedError gracefully#489
alvinkam2001 merged 2 commits into
nextfrom
akam/task-create-idempotency

Conversation

@alvinkam2001

@alvinkam2001 alvinkam2001 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Makes task/create idempotent in the Temporal ACP path. Duplicate submits for the same task ID (e.g. load-balanced agentex-agent replicas racing on the same notification) no longer surface WorkflowAlreadyStartedError, Temporal returns the existing workflow handle instead.

Change

  • TemporalTaskService.submit_task now passes id_conflict_policy=WorkflowIDConflictPolicy.USE_EXISTING.
  • TemporalClient.start_workflow accepts an id_conflict_policy param (defaults to UNSPECIFIED, preserving current behavior for any other caller).

Why

WorkflowIDReusePolicy.ALLOW_DUPLICATE (already set) only governs reuse after a run closes — it doesn't help when a run is currently open. Workflows are mainly just noise as the workflow still runs

Test plan

  • New unit tests in tests/lib/core/services/test_temporal_task_service.py:
    • submit_task passes USE_EXISTING to the client
    • TemporalClient.start_workflow forwards id_conflict_policy when set
    • TemporalClient.start_workflow defaults to UNSPECIFIED (backwards-compat)
  • Existing TemporalTaskService tests still pass
  • Sanity check in staging: fire two task/create calls with the same task ID, confirm both return 200 with the same workflow ID and no error log

Greptile Summary

The PR makes Temporal-backed task/create submissions idempotent while preserving the existing default behavior for other workflow starts.

  • Adds a local conflict-policy enum and maps it to Temporal SDK policies.
  • Uses USE_EXISTING when submitting task workflows.
  • Adds unit coverage for service forwarding, default behavior, and invalid policy combinations.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/agentex/lib/core/clients/temporal/temporal_client.py Adds conflict-policy mapping and forwarding while retaining an unspecified default for existing callers.
src/agentex/lib/core/clients/temporal/types.py Introduces a wrapper enum corresponding to Temporal workflow-ID conflict policies.
src/agentex/lib/core/temporal/services/temporal_task_service.py Configures task workflow starts to return an existing handle when the workflow ID is already active.
tests/lib/core/services/test_temporal_task_service.py Covers task-service idempotency configuration, policy mapping, defaults, and invalid combinations.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant TaskService as TemporalTaskService
    participant Wrapper as TemporalClient
    participant Temporal
    Caller->>TaskService: submit_task(task ID)
    TaskService->>Wrapper: start_workflow(USE_EXISTING)
    Wrapper->>Temporal: "start_workflow(id_conflict_policy=USE_EXISTING)"
    alt Workflow ID is already running
        Temporal-->>Wrapper: Existing workflow handle
    else Workflow ID is available
        Temporal-->>Wrapper: New workflow handle
    end
    Wrapper-->>TaskService: Workflow ID
    TaskService-->>Caller: Workflow ID
Loading

Reviews (3): Last reviewed commit: "address comments" | Re-trigger Greptile

@alvinkam2001
alvinkam2001 force-pushed the akam/task-create-idempotency branch from dbfcca6 to 58c27ea Compare August 7, 2026 00:33

@jromualdez-scale jromualdez-scale left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took a look — the change itself makes sense to me. The reuse vs conflict policy distinction is the right diagnosis and USE_EXISTING is literally what temporalio documents for this ("Set to USE_EXISTING for idempotent deduplication on workflow ID"), so no concerns there.

Couple of non-blocking comments on the wrapper API below.

Comment thread src/agentex/lib/core/clients/temporal/temporal_client.py Outdated
Comment thread src/agentex/lib/core/clients/temporal/temporal_client.py Outdated
@alvinkam2001
alvinkam2001 merged commit 462195d into next Aug 7, 2026
48 checks passed
@alvinkam2001
alvinkam2001 deleted the akam/task-create-idempotency branch August 7, 2026 20:45
@stainless-app stainless-app Bot mentioned this pull request Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants