Generated banner for Temporal Ops
Generated logo for Temporal Ops

Temporal Ops

OpenAIOfficialCreated by TemporalDistributed by OpenAI

  • Skill
  • Tool integration
  • Cloud and DevOps
  • MIT
  • No issues found

From the author

Administer and diagnose running Temporal Cloud or self-hosted Temporal Server environments via CLI (temporal, tcld) — not SDK code. Operations: namespace CRUD, Cloud capacity/APS, API-key rotation, mTLS cert rotation, workflow health, batch cancel/terminate/reset, export, search attributes, Ops API, billing, audit logs, Terraform, SAML/SCIM, migration. Diagnosis: bottom-up triage of stuck workflows, non-determinism, worker-health, task-queue problems, HA failover, payload size limits, performance bottlenecks, missed schedules. Do NOT trigger for generic TLS/gRPC errors unrelated to Temporal, writing application code (temporal-developer), or worker tuning/sizing (temporal-workertuning).
— the description by Temporal

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured approach to managing and troubleshooting Temporal environments. It covers two primary modes: Operations, for administrative tasks like namespace management, API key rotation, and batch workflow actions; and Diagnosis, for investigating issues like stuck workflows, connectivity errors, and performance bottlenecks. It enforces strict operational discipline, including explicit confirmation for destructive commands and a bottom-up diagnostic methodology to ensure root causes are identified accurately.

What it does

  • Performs administrative operations on Temporal Cloud via tcld and self-hosted clusters via temporal operator.
  • Executes batch operations on workflows using query-based filtering with safety-first confirmation steps.
  • Diagnoses system issues using a layered, bottom-up approach from network connectivity to workflow logic.
  • Manages security configurations including API keys, mTLS certificates, and SAML/SCIM integrations.
  • Provides guidance on interpreting audit logs and cloud capacity metrics.
  • Routes complex tasks to specialized skills for development, worker tuning, or infrastructure configuration.

When to use it

  • When you need to perform administrative tasks like creating namespaces or rotating credentials.
  • When a Temporal environment is experiencing errors such as connection timeouts or authentication failures.
  • When you need to investigate or recover from stuck, non-deterministic, or unhealthy workflows.
  • When you need to perform bulk operations on workflows and require a safe, verified execution process.
  • When you need to audit or monitor the health and capacity of your Temporal Cloud account.

Advantages

  • Enforces safe operational practices by requiring explicit approval for destructive commands.
  • Provides a systematic diagnostic ladder to avoid speculative fixes.
  • Distinguishes clearly between Cloud and self-hosted administrative procedures.
  • Integrates safety checks like counting affected workflows before executing batch mutations.
  • Standardizes the interpretation of common gRPC and Temporal-specific error codes.

Usage examples

“How do I rotate my mTLS certificates for my Temporal Cloud namespace?”
The agent will guide you through the tcld commands for generating new certificates and updating the namespace configuration, ensuring you follow the correct rotation sequence.
“I am seeing 'context deadline exceeded' errors in my workflow. How do I debug this?”
The agent will initiate a bottom-up diagnosis, starting by verifying network connectivity and gRPC health before investigating specific workflow task execution logs.
“Terminate all workflows of type 'OrderProcessing' that are currently stuck.”
The agent will first run a count to identify the number of affected workflows, present this number to you for confirmation, and then execute the batch termination only after your approval.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/openai/temporal-ops/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip temporal-ops.zip -d .agents/skills

Documentation by Temporal

Skill: temporal-ops

Overview

This skill operates and diagnoses Temporal environments. It has two modes:

  • Operations: the user wants to do something — create a namespace, rotate a key, check capacity, find unhealthy workflows, cancel a batch, set up export. The skill executes the right commands and interprets the output.

  • Diagnosis: the user arrives with a symptom — a stuck workflow, a cert error, a connection timeout, a non-determinism panic. The skill routes the investigation through a layered, bottom-up diagnosis until a root cause is identified with a confidence score.

It does not teach how to write workflows or activities (use skill-temporal-developer for that), and it does not reproduce exhaustive CLI flag tables — run temporal <cmd> --help for those, and see cli-conventions.md for cross-command CLI conventions. The boundary is: if the user needs to administer or troubleshoot a running Temporal environment, this skill applies.

Out of scope

  • Writing workflows, activities, or SDK code → skill-temporal-developer.

  • Exhaustive CLI flags / command reference → run temporal <cmd> --help; cross-command CLI conventions → cli-conventions.md.

  • Worker performance tuning, sizing, capacity planning → skill-temporal-workertuning.

  • Helm, Kubernetes, database admin, monitoring stack config for self-hosted — beyond the CLI surface.

If the conversation drifts into one of these areas, hand off to the relevant sibling skill rather than improvising.

Philosophy

Operator discipline

When the user wants to perform an operational task:

  1. Identify the intent and backend. Is this a Cloud operation (tcld) or a self-hosted operation (temporal operator)? Data-plane operations (temporal workflow, temporal batch, etc.) work on both. If the backend is ambiguous, ask before proceeding — do not assume Cloud or self-hosted and do not output environment-specific commands until you know.

  2. Execute commands and interpret output. Run the documented command, read the result, and report what it means — or act on it if the user asked for an action. Read-only commands (get, list, describe, count, show) run freely. Anything listed under Destructive operations is proposed to the user first.

  3. Verify the result. After a mutating operation, confirm the new state matches the user's intent.

Destructive operations

An operation belongs to this tier if it is irreversible (tcld namespace delete), revokes access for a live identity (tcld apikey delete), moves production traffic (tcld namespace failover), or fans out to every match (any --query form). Apply the test to the operation in front of you — this is a rule, not a list, and a command's absence from any list in this skill does not place it outside the tier.

For anything in the tier: gather the evidence and propose. Do not run it on your own initiative, and do not run one to find out what it would do. The reference file for each command states its specific blast radius; read that before proposing, not after.

  1. Blast radius as a number, not a description. For any --query form, run temporal workflow count --query '<query>' with the byte-identical query first and carry the result into the proposal. A filter with no narrowing predicate beyond ExecutionStatus="Running" matches every open Execution in the Namespace.

  2. Name the target. State the exact command, the target, and the Namespace it resolves to. Connection settings can come from TEMPORAL_* env vars or a config-file profile, so the target is frequently not visible in the command text. If the backend or Namespace was inferred from context rather than stated by the user, say so — a destructive command aimed at the wrong Namespace is the most common way this goes wrong.

  3. Ask explicitly, then run it so it completes. Put the command, the target, and — for any --query form — the count from step 1 to the user as a direct question, and wait for an answer. Once they approve, run it with --yes on the --query batch forms; that flag is what lets an approved batch finish, since the interactive prompt needs a terminal and without one the command reports user denied confirmation and does nothing. --yes belongs in a command the user approved, never in a retry of one that failed its prompt. Do not substitute a loop over single-target workflow terminate --workflow-id. Approval covers one command against one target; it does not carry to the next command, a widened query, or a second Namespace.

  4. Verify, and know the abort path. Re-run the corresponding get, describe, or count. A batch job drains asynchronously: temporal batch describe --job-id <id> shows how far it has gotten and temporal batch terminate --job-id <id> stops it before it reaches the rest of its matches.

When a reversible sibling reaches the same goal, propose it alongside: cancel lets Workflow cleanup code run where terminate does not; apikey disable is reversible where delete is not; accepted-client-ca add appends where set replaces.

Assume nothing in the environment will stop a destructive command on your behalf. Credential scope, command denylists, and confirmation prompts may or may not be configured, and their possible presence is not a reason to skip any step above — you are the safeguard the user is relying on.

Diagnostic discipline

When the user arrives with a failure or anomaly:

  1. Bottom-up diagnosis. Verify the lower layer before blaming the upper one. The layers, from bottom to top:

    1. DNS / network path

    2. TCP / port reachability

    3. TLS handshake

    4. Authentication (API key or mTLS client cert)

    5. gRPC health and Temporal frontend reachability

    6. Temporal namespace, task queues, workers

    7. Workflow code (determinism, signals, timers, child workflows)

    The full ladder lives in diagnostic-ladder.md.

  2. Always verify the next layer up rather than prescribing a speculative fix. If TLS works, prove auth works before blaming the workflow. If pollers are present, prove the workflow's last event before blaming the worker.

  3. Attach a confidence score (1-10) to every proposed diagnosis:

    • 9-10: symptoms, operation, and confirming signals line up cleanly.

    • 6-8: evidence is good but at least one alternative remains plausible.

    • 1-5: the issue is still ambiguous; the "fix" is the next discriminating check, not a root cause.

  4. Name ambiguity explicitly. Errors like context deadline exceeded are not self-describing, and a single code such as RESOURCE_EXHAUSTED can mean more than one condition (account-limit throttling vs. per-Workflow lock contention). Surface that, gather more context, and scope the next step narrowly.

These are skill conventions, not docs-derived facts.

Intent routing

Operations

Find the row that matches the user's intent. The reference file contains the commands and procedures.

IntentCategoryReference
Create, get, list, delete a Cloud namespaceCloud namespace admincloud-namespace-admin.md
Add/remove region, failover, HA configCloud namespace admincloud-namespace-admin.md
Set retention, tags, codec-server, connectivity rulesCloud namespace admincloud-namespace-admin.md
Add or rename Cloud search attributesCloud namespace admincloud-namespace-admin.md
Check current APS / capacity modeCloud capacitycloud-capacity.md
Switch On-Demand ↔ Provisioned, set TRUsCloud capacitycloud-capacity.md
Understand APS / RPS / OPS limits and throttlingCloud capacitycloud-capacity.md
Create, disable, enable, delete an API keyCloud IAMcloud-iam.md
Invite, list, remove users; set roles/permissionsCloud IAMcloud-iam.md
Manage user groups and service accountsCloud IAMcloud-iam.md
Generate mTLS certs, upload CA, set cert filtersCloud certscloud-certs.md
Rotate mTLS certificatesCloud certscloud-certs.md
Set up Workflow History Export (S3 / GCS)Cloud namespace admincloud-namespace-admin.md
Set up PrivateLink / PSC, manage connectivity rulesCloud connectivitycloud-connectivity.md
Self-hosted cluster health, describe, namespace CRUDSelf-hosted adminself-hosted-admin.md
Self-hosted search attributes, Nexus endpointsSelf-hosted adminself-hosted-admin.md
Check or manage a Cloud Nexus Endpoint's caller-Namespace allowlist; the 1,000-caller defaultCloud namespace admincloud-namespace-admin.md#tcld-nexus-endpoint-allowed-namespace
Find stuck/hung/unhealthy workflows via list queriesWorkflow healthworkflow-health.md
Task queue poller status, workflow countsWorkflow healthworkflow-health.md
Cancel, terminate, or reset workflowsWorkflow recoveryworkflow-stuck.md#recovery-commands
Bulk / batch operations on workflows (--query)CLI conventionscli-conventions.md
Schedule CRUD, time-spec, and operationsCLI conventionscli-conventions.md
Complete or fail an activity externallyCLI conventionscli-conventions.md
Cloud Ops API access, rate limits, Go SDKCloud Ops APIcloud-ops-api.md
View billing, generate billing report, cost attributionCloud billingcloud-billing.md
Audit Logs: view, query via API, configure sink (AWS/GCP)Cloud audit logscloud-audit-logs.md
Terraform provider: Namespace/User/SA/API Key/Nexus CRUDCloud Terraformcloud-terraform.md
Expiry alerts (cert, API key, credit), status pageCloud notificationscloud-notifications.md
SAML SSO, SCIM provisioning, IdP integrationCloud SAML/SCIMcloud-saml-scim.md
Migrate self-hosted to Cloud (automated or manual), migrate between Cloud regionsCloud migrationcloud-migration.md
End-to-end ops playbook (setup, rotation, audit, billing, Terraform)Ops recipesops/recipes.md
Diagnosis

Find the row that matches the user's symptom. Start the investigation at the first check, then read the linked reference.

SymptomCategoryFirst checkReference
connection refused, cannot reach frontendConnectivitync -zvw10 <host> 7233connectivity.md#connection-refused
no such host, DNS resolution failsConnectivitydig +short <host> or nslookup <host>connectivity.md#dns
tls: handshake failure, server rejects handshakeCertificatesopenssl s_client -connect <host>:7233 -servername <host> </dev/nullcertificates.md#handshake-failure
x509: certificate has expired or not yet validCertificatesopenssl x509 -enddate -noout -in cert.pemcertificates.md#expired-or-not-yet-valid
x509: certificate signed by unknown authorityCertificatesopenssl verify -CAfile ca.pem client.pemcertificates.md#unknown-authority
tcld session / auth fails, Cloud role unclearAuthenticationtcld account getauthentication.md#cloud-role-and-permission-model
UNAUTHENTICATED, API key rejectedAuthenticationenv | grep -i TEMPORAL_API_KEY, then tcld apikey get --id <apikey_id>authentication.md#things-to-check-when-unauthenticated-is-returned-with-an-api-key
namespace not found / wrong namespace string with an API keyAuthenticationConfirm Regional Endpoint form <region>.<cloud_provider>.api.temporal.io:7233authentication.md#address-form-for-api-key-connections
RESOURCE_EXHAUSTED gRPC statusRate limitsIdentify which limit fired: throttle metrics on Cloud v1, the resource_exhausted_cause label on v0 / self-hostedrate-limits.md#identifying-which-limit-was-hit
Task queue shows no pollersWorker healthtemporal task-queue describe --task-queue <q>worker-health.md#what-no-pollers-looks-like
Workflow stuck on a pending activity / timer / child / signalWorkflow stucktemporal workflow describe --workflow-id <id>workflow-stuck.md#the-primary-inspection-command-temporal-workflow-describe
NondeterminismError, repeating WorkflowTaskFailedNon-determinismIdentify the last WorkflowTaskFailed cause in the Event Historynon-determinism.md#the-wft-failure-signature-of-non-determinism
Replay fails locally but prod workflow was runningNon-determinismFetch the history and run the SDK replayer in one testreplay.md#step-2--run-the-sdk-replayer-all-supported-sdks
HA failover did not route traffic to failover regionHA failovertcld namespace get --namespace <ns>.<acct> vs. DNS CNAMEha-failover.md#start-here-establish-ground-truth
Serverless Worker (AWS Lambda) stopped processing work after a Namespace failoverHA failoverConfirm a FailoverNamespace audit event, then compare the new active region against the Lambda ARN on the Worker Deployment Versionha-failover.md#symptom-serverless-workers-kept-running-in-the-old-region-after-failover
context deadline exceeded (unknown layer)Runtime errorsIdentify which operation and SDK emitted itruntime-errors.md#deadline-exceeded
Workflow is busy / ResourceExhausted on signal/update/query to one Workflow (BusyWorkflow)Runtime errorsRule out account-limit throttling, then split temporal_cloud_v1_resource_exhausted_error_count by operationruntime-errors.md#workflow-lock-contention-busyworkflow
PAYLOADS_TOO_LARGE, exceeds size limit, payload/gRPC blob size errorBlob size limitsCheck whether the issue is payload (2 MB) or gRPC message (4 MB)blob-size-limits.md
Workflow stuck in invisible retry loop (gRPC message too large)Blob size limitsCheck Worker logs for ResourceExhausted, reduce batch sizeblob-size-limits.md
High schedule-to-start latency, task slot depletion, slow Workflow TasksPerformance bottlenecksCheck temporal_workflow_task_schedule_to_start_latency P95performance-bottlenecks.md
High replay latency, cache evictions, deadlock detectedPerformance bottlenecksCheck workflow_task_replay_latency and sticky cache metricsperformance-bottlenecks.md
Schedule did not fire, missed catchup windowMissed Schedule ActionsAlert on temporal_cloud_v1_schedule_missed_catchup_window_countschedule-missed.md

If a symptom does not map to a row, start at diagnostic-ladder.md and work up from whichever layer was last known healthy.

The process

Operations path
Step 1: Identify intent and backend

Determine what the user wants to do and whether it targets:

  • Temporal Cloud → use tcld commands (requires tcld login)

  • Self-hosted cluster → use temporal operator commands

  • Data plane (either backend) → use temporal workflow, temporal batch, temporal schedule, etc.

If the backend is unambiguous from context — .tmprl.cloud address, tcld command, Cloud namespace format ns.account → Cloud; Kubernetes/Helm, docker-compose, self-hosted config files → self-hosted — proceed without asking. Otherwise, stop and ask: "Are you on Temporal Cloud or self-hosted?" before outputting any environment-specific commands. Do not default to either environment. Once known, save the answer to memory so you don't ask again in future conversations.

Step 2: Execute and interpret

Look up the intent in the Operations table above. Read the linked reference file for the exact commands, flags, and expected output. Run the command and interpret the result for the user.

Step 3: Verify

After a mutating operation (create, update, delete, rotate), confirm the new state:

  • Re-run the corresponding get or describe command

  • Confirm the output matches the user's intent

  • Report the result

Diagnosis path
Step 1: Identify the symptom

Ask the user for the exact, copy-pasted error text. Do not accept paraphrases — the exact string often encodes the layer (e.g., x509: prefix means TLS/cert layer, RESOURCE_EXHAUSTED: prefix means gRPC rate limit, NondeterminismError means workflow replay layer). Note that RESOURCE_EXHAUSTED alone does not tell you which condition fired — account-limit throttling and per-Workflow lock contention (Workflow is busy, i.e. BusyWorkflow) share the code. Split the resource-exhausted metric by its label (operation on the Cloud v1 family, resource_exhausted_cause on v0 and self-hosted) rather than parsing the free-text message.

Confirm three things before continuing:

  • What command was run, or what SDK call produced the error?

  • What environment produced it (local dev server, self-hosted cluster, Temporal Cloud)? If clear from context (addresses, commands, namespace format), don't ask — but if uncertain, ask now before proceeding with any diagnosis. Save the answer to memory for future conversations.

  • What changed recently (new deploy, new certs, new namespace, new region)?

Step 2: Gather context

The context the investigation needs depends on the category. At minimum:

  • For any Cloud auth / connectivity issue: auth method (API key vs mTLS), exact address, exact namespace, SDK + version. The endpoint family differs by auth method — see connectivity.md#endpoint-formats. For private connectivity (PrivateLink / PSC), TLS server name overrides also vary by auth method — see cloud-connectivity.md.

  • For a stuck workflow: namespace, workflow ID, run ID, and the output of temporal workflow describe --workflow-id <id> (pending-operation state lives here, not in the Event History alone). Event History via temporal workflow show is the companion view.

  • For a worker health issue: worker logs (registration errors, auth errors, panics), the output of temporal task-queue describe --task-queue <q>, and temporal worker describe --task-queue <q> for per-worker details.

  • For a non-determinism error: the worker log line containing the error, the workflow type name, and access to the history JSON for replay.

Step 3: Validate pasted SDK config (if any)

If the user has pasted SDK connection code — even just the address/namespace/auth fields — review it against sdk-snippet-review.md before descending the ladder. Wrong endpoint family, short namespace, or mismatched auth method will make every network-layer probe below look broken when nothing lower actually is.

Skip this step when the user has an established, previously-working config and the symptom is new — the snippet is not the culprit, the environment changed. Otherwise treat snippet validation as Layer 0.

Step 4: Descend the ladder

Use diagnostic-ladder.md to pick the right starting layer. As a rule of thumb:

  • Auth / connectivity / cert symptom → start at layer 1 (DNS) and walk up.

  • Worker / task-queue symptom → start at layer 6 (namespace + pollers).

  • Stuck workflow / determinism symptom → start at layer 7 (workflow code), but confirm layer 6 (worker is actually polling) first.

Each layer has a command that proves it healthy and a failure signature that tells you whether the problem lives at that layer or higher.

Step 5: Fix and verify

Prescribe the fix scoped to the root cause. Then verify by re-running the layer's healthy-check command and, if possible, the original user operation. Attach the confidence score to the diagnosis.

If the layer above the fix is still failing, return to step 4 and continue walking upward — the first broken layer is rarely the only one.

Prerequisites

  • Temporal CLI (temporal) — required for data-plane operations and self-hosted admin. Install: brew install temporal or see Temporal CLI docs.

  • tcld — required for Cloud operations. Install: brew install temporal-cloud-cli or see tcld docs. Authenticate with tcld login before use.

Reference files

Operations
  • cloud-namespace-admin.md — Cloud namespace lifecycle via tcld: create, get, list, delete, failover, add-region, retention, tags, codec-server, HA config, connectivity rules, search attributes, accepted-client-ca, certificate filters, export, and the tcld nexus endpoint allowed-namespace caller allowlist (1,000-caller Access Policy ceiling).

  • cloud-capacity.md — Capacity modes (On-Demand / Provisioned), APS/RPS/OPS definitions, TRUs, tcld namespace capacity update, default limits, throttling, APS management best practices.

  • cloud-iam.md — API key lifecycle (tcld apikey), users (tcld user), user groups (tcld user-group), service accounts, account operations (tcld account), roles, namespace permissions.

  • cloud-certs.md — mTLS cert management: generating certs with tcld generate-certificates, uploading CAs, certificate filters, cert rotation, switching mTLS ↔ API keys.

  • cloud-connectivity.md — Private connectivity (AWS PrivateLink / GCP PSC), connectivity rules: setup, rule parameters, tcld commands, attaching rules to namespaces.

  • cloud-migration.md — Migration paths: automated self-hosted→Cloud (S2S proxy, tcld migration commands, 5 phases), manual self-hosted→Cloud (client changes, workflow strategies), within-Cloud region-to-region (HA add-region/failover).

  • cloud-ops-api.md — Cloud Ops API: HTTP and gRPC endpoints (saas-api.tmprl.cloud), Go SDK, protobuf compilation, rate limits (160 RPS account, 40 user, 80 SA, 10 concurrent async), API version header, use cases.

  • cloud-billing.md — Cloud billing: Billing Center (invoices, credits, plans, cost by namespace), Usage Dashboards, Billing API: async CSV report generation, FOCUS-friendly format, 27-column report schema, date range constraints.

  • cloud-audit-logs.md — Cloud Audit Logs: supported control plane events (Account, API Keys, Connectivity Rules, Namespace, Export, Nexus, Service Accounts, User, User Groups), JSON format, API access (30-day retention), AWS Kinesis and GCP Pub/Sub sink configuration.

  • cloud-terraform.md — Terraform provider: setup (TEMPORAL_CLOUD_API_KEY), temporalcloud_namespace/temporalcloud_user/temporalcloud_service_account/temporalcloud_apikey/temporalcloud_nexus_endpoint CRUD, import, data sources (regions, namespaces), limitations (API keys not importable, cannot manage Account Owner).

  • cloud-notifications.md — Cloud notifications: certificate expiry (15/10/5 days), API key expiry (30/20/10 days), credit consumption/expiry alerts, plan changes, failover events, recipient roles, [email protected] sender.

  • cloud-saml-scim.md — SAML SSO (Entra ID, Okta): entity identifier (urn:auth0:prod-tmprl:ACCOUNT_ID-saml), callback URL (login.tmprl.cloud), IdP configuration steps, support ticket workflow. SCIM: supported vendors, prerequisites (SAML first), 10-minute sync window, group-to-role mapping.

  • self-hosted-admin.md — Self-hosted control plane via temporal operator: cluster health/describe, namespace CRUD, search-attribute create/list/remove, Nexus endpoint CRUD.

  • workflow-health.md — Data-plane health queries: temporal workflow list with List Filters, temporal workflow describe/show/count, temporal task-queue describe for poller status.

  • cli-conventions.md — Cross-command temporal CLI conventions: connection/identity (TEMPORAL_* env vars ↔ --address/--namespace/--api-key, --identity), output/formatting (--output, --time-format, payload shorthand), the --query ⇒ batch-job bridge (with temporal batch describe/list/terminate), and schedule time-spec forms. Ends with an operation→command index that routes each data-plane operation to its owner file. Delegates exhaustive flags to temporal <cmd> --help.

  • ops/recipes.md — End-to-end ops playbooks: set up new namespace, check APS, switch capacity mode, find hung workflows, rotate API key, audit access, rotate mTLS certs, check self-hosted health, view billing / generate billing report, configure audit log sink, provision resources with Terraform, set up SAML SSO.

Diagnosis
  • sdk-snippet-review.md — Layer-0 config check for pasted SDK connection snippets: endpoint form per auth method, namespace format, auth / TLS expectations, TEMPORAL_* env vars, common misconfigurations. Run before the diagnostic ladder.

  • diagnostic-ladder.md — the seven-layer bottom-up model, with one canonical command per layer and cross-links into the topical leaves.

  • connectivity.md — DNS, TCP, endpoint families (Namespace Endpoint for mTLS vs. Regional Endpoint for API keys), firewall/proxy shapes, PrivateLink/PSC, quick diagnostic scripts.

  • certificates.md — x509 and TLS alert strings, expiry / unknown-authority / hostname-mismatch / key-mismatch diagnosis, Cloud accepted-client-CA set via tcld namespace accepted-client-ca, Cloud mTLS certificate requirements, rotation and expiry notifications, openssl recipes.

  • authentication.md — UNAUTHENTICATED vs PERMISSION_DENIED, API-key lifecycle (tcld apikey commands, env var propagation, required Regional Endpoint form), mTLS after TLS (certificate filters, identity-to-role mapping), Cloud account-level roles and namespace-level permissions.

  • workflow-stuck.md — Workflow Execution Status values, temporal workflow describe as the primary inspection command, Event History via temporal workflow show, pending activities / child workflows / signals / Nexus operations / Workflow Tasks, WorkflowTaskFailed retry loops, recovery commands (signal, terminate, cancel, reset, pause/unpause).

  • non-determinism.md — determinism definition, WFT-failure signature, ND-inducing code patterns, per-SDK error shapes, identifying ND from Event History, local replay reproduction, remediation via Worker Versioning / patching / reset.

  • worker-health.md — no-pollers runbook via temporal task-queue describe, reachability and versioning, worker-level describe, schedule-to-start latency, worker task slots, sticky execution and sticky cache, worker heartbeating, Cloud namespace-level poller limits, worker log signatures.

  • rate-limits.md — what RESOURCE_EXHAUSTED means (and does not), Cloud APS / RPS / OPS under On-Demand and Provisioned capacity modes, self-hosted frontend.rps / frontend.namespaceRPS dynamic config, identifying which limit fired via the throttle metrics (Cloud v1) or the resource_exhausted_cause label (v0 / self-hosted), and separating account-limit throttling from single-resource exhaustion.

  • ha-failover.md — Cloud HA routing via the Namespace Endpoint CNAME, verifying the active region (control-plane tcld namespace get vs. DNS view), clients that did not follow the failover, PrivateLink after failover, failover-not-executing, handover-window errors, platform limits, RPO/RTO semantics, and Serverless Workers (AWS Lambda) not following a failover because compute-provider configuration is region-scoped.

  • runtime-errors.md — deadline-exceeded disambiguated by operation and by where the call was made, Workflow lock contention (BusyWorkflow) separated from account-limit throttling and confirmed via the operation breakdown, routing for no pollers / INVALID_ARGUMENT / unspecified UNAVAILABLE.

  • replay.md — fetching Event History with the SDK client (CLI export as fallback), running the SDK replayer in every supported SDK (Go, Python, TypeScript, Java, .NET, Ruby, PHP), TEMPORAL_DEBUG and the deadlock detector, interpreting divergent and successful replays, and the TypeScript-only VS Code extension.

  • blob-size-limits.md — Payload size limit (2 MB) and gRPC message size limit (4 MB): error messages, per-SDK behavior (Python 1.23.0+ vs. others), claim check pattern, External Storage (Pre-release), batch-size reduction.

  • performance-bottlenecks.md — Latency and throughput diagnosis via SDK metrics: schedule-to-start latency, workflow task execution latency, replay latency, activity execution latency, task slot depletion, network request metrics, sticky cache metrics.

  • schedule-missed.md — Missed Schedule Actions: alerting via temporal_cloud_v1_schedule_missed_catchup_window_count / schedule_missed_catchup_window, investigation via temporal schedule list + temporal schedule describe, DescribeSchedule fields (missedCatchupWindow, overlapSkipped, bufferDropped), default catchup window (one year), root causes, overlap policies (6 values), backfill remediation.

  • recipes.md — four end-to-end triage walkthroughs: stuck workflow at 3am, cert expired with workers offline, task-queue backlog mystery, non-determinism caught in prod.

Feedback

Feedback prompt

When you have first loaded this skill, output this message to the user:

"Thank you for trying out the public preview of the Temporal Ops skill! We would love to hear your feedback - positive or negative - over in the Community Slack, in the #topic-ai channel."

Do not output this message multiple times in the same conversation.

Reporting Issues in This Skill

If you (the AI) find this skill's explanations are unclear, misleading, or missing important information, draft a GitHub issue body describing the problem encountered and what would have helped, then ask the user to file it at https://github.com/temporalio/skill-temporal-ops/issues/new. Do not file the issue autonomously.

Files

references/triage/workflow-stuck.md

Workflow Stuck

A Workflow Execution exists, is reachable, reports an Open status, but is not making progress. This file scopes to what the server sees when that is true: the execution's own state as surfaced by temporal workflow describe, the append-only Event History as surfaced by temporal workflow show, and the pending-operation sub-structures (pending activities, pending child workflows, pending nexus operations, pending workflow task) that describe exposes.

Prerequisite: the client can reach the Temporal Service, authenticate, and issue data-plane RPCs. If temporal workflow describe itself fails, the problem is not in this file — rule out earlier layers via connectivity.md, certificates.md, authentication.md, and rate-limits.md.

Out of scope here:

  • Task Queue has no pollers / workers not polling → worker-health.md

  • Replaying recorded history diverges from the compiled Workflow (non-determinism) → non-determinism.md

  • Replaying an Event History locally under a debugger → replay.md

  • gRPC RESOURCE_EXHAUSTED when the client call to describe/signal/query was itself rate-limited → rate-limits.md

  • context deadline exceeded on the client side → runtime-errors.md

Table of Contents

  • What "stuck" means

  • Workflow Execution Status values

  • The primary inspection command: temporal workflow describe

  • Inspecting the Event History: temporal workflow show

  • Pending activities

  • Pending child workflows

  • Pending signals, cancellations, and updates

  • Pending Nexus Operations

  • Pending Workflow Task and WorkflowTaskFailed loops

  • Timer-based waits

  • Pending-operation per-Workflow limits

  • Recovery commands

  • Quick routing

What "stuck" means

"Stuck" is not a Temporal-defined state. It is a user observation that requires server evidence to classify. The three shapes of evidence that reliably separate "stuck" from "running as designed":

  • Event History has grown recently, but the last non-bookkeeping event is a scheduling event with no corresponding terminal event. For example, ActivityTaskScheduled appears with no ActivityTaskCompleted / ActivityTaskFailed / ActivityTaskTimedOut appended for an interval longer than expected.

  • temporal workflow describe shows a pending activity, child workflow, nexus operation, or workflow task whose attempt count is climbing and whose last failure reason is reported. Per the Activity Operations observability guide: "temporal workflow describe shows the current state of each pending Activity, including whether it's Paused, its current attempt count, and last failure."

  • Event History has not grown for longer than the longest timer or timeout currently outstanding. A workflow can legitimately wait years on a Timer or indefinitely on a signal. Absence of progress is only evidence of stuck-ness when it exceeds the longest outstanding deadline the Workflow itself established.

All three rely on comparing the Workflow's own records (history + describe output) against expectations. Neither the SDK nor the server synthesises a single "Workflow is stuck" signal — the evidence lives in the fields below.

Workflow Execution Status values

A Workflow Execution is either Open or Closed. The full canonical set of statuses surfaced through the ExecutionStatus Search Attribute is: Running, Completed, Failed, Canceled, Terminated, ContinuedAsNew, TimedOut.

StatusOpen/ClosedMeaningSource
RunningOpen"The only Open status for a Workflow Execution. When the Workflow Execution is Running, it is either actively progressing or is waiting on something."
CompletedClosed"The Workflow Execution has completed successfully."
FailedClosed"The Workflow Execution returned an error and failed."
CanceledClosed"The Workflow Execution successfully handled a cancellation request."
TerminatedClosed"The Workflow Execution was terminated."
ContinuedAsNewClosed"The Workflow Execution Continued-As-New."
TimedOutClosed"The Workflow Execution reached a timeout limit."

A "stuck" Workflow is almost always in Running. The phrase "either actively progressing or waiting on something" is the core ambiguity this file exists to resolve: Running alone cannot distinguish "working" from "wedged." The describe output and history are what distinguish them.

Transitions terminate the run:

  • A Workflow Execution retry caused by its Retry Policy ends the failed run with Failed (status Failed, retryState=IN_PROGRESS, newExecutionRunId set) and spawns a new run.

  • Continue-As-New closes the current run with ContinuedAsNew and starts a new run in the same Workflow Execution Chain.

  • A Workflow Execution Timeout produces status TimedOut.

  • The Event History reaching 51,200 events, 2,000 Updates, or 10,000 Signals terminates the Workflow Execution.

If the user reports a stuck workflow whose describe output shows a Closed status, they are not describing a stuck workflow — they are describing a completed or failed one, and the rest of this file does not apply.

The primary inspection command: temporal workflow describe

temporal workflow describe is the one command that reports the server's current view of a single Workflow Execution's state. This file's diagnosis rests on the shape of its output.

temporal workflow describe \
    --workflow-id YourWorkflowId

Flags:

FlagRequiredPurpose
--workflow-id, -wYesWorkflow ID.
--run-id, -rNoRun ID. If omitted, the most recent run in the Workflow Execution Chain is described.
--reset-pointsNo"Show auto-reset points only."
--rawNo"Print properties without changing their format."
--output, -oNo (global)Output format. Accepted values: text, json, jsonl, none.
Reading the output

The text example shown in the CLI docs for a minimal Running execution exposes these top-level fields: executionConfig, workflowExecutionInfo (containing execution.workflowId, execution.runId, type.name, startTime, status, historyLength, executionTime, memo, autoResetPoints, stateTransitionCount), and pendingWorkflowTask (containing state, scheduledTime, originalScheduledTime, attempt).

The Nexus-operations and pending-activities text examples in the encyclopedia show an alternative tabular shape under the same command — Pending Activities: N, Pending Child Workflows: N, Pending Nexus Operations: N, each followed by an indented block.

Which sections appear depends on the Workflow's current state: a Workflow with no pending operations simply won't show those sections.

What to look at first

Per the intake shape above, the three checks that partition the problem:

  1. workflowExecutionInfo.status — if it's anything other than Running, the workflow is Closed, not stuck. See Workflow Execution Status values.

  2. Pending sections present — are there Pending Activities, Pending Child Workflows, Pending Nexus Operations, or a pendingWorkflowTask? Each maps to a section below.

  3. historyLength — stored in workflowExecutionInfo.historyLength. If it is climbing between successive describes but the pending sections don't resolve, events are being written but the Workflow is cycling. If it is flat with no pending operations, the Workflow is asleep on something with no visible pending work (typically a Timer — see Timer-based waits).

Inspecting the Event History: temporal workflow show

temporal workflow show returns the Event History, the append-only log of Events that drives replay.

temporal workflow show \
    --workflow-id YourWorkflowId \
    --output json

Flags:

FlagRequiredPurpose
--workflow-id, -wYesWorkflow ID.
--run-id, -rNoRun ID.
--detailedNo"Display events as detailed sections instead of table. Does not apply to JSON output."
--follow, -fNo"Follow the Workflow Execution progress in real time. Does not apply to JSON output."
--output jsonNo (global)Emits the JSON shape an SDK would replay.

Event types are enumerated in the Events reference; the canonical list is the EventType proto enum. A Command issued by the Workflow code produces a corresponding Event on the server — the Command/Event mapping is documented in the Commands reference.

Finding the last meaningful event

Within each Workflow Task execution, the server records WorkflowTaskScheduled, WorkflowTaskStarted, and WorkflowTaskCompleted bookkeeping around the state changes the Workflow code produced. When diagnosing stuck-ness, the event type that exposes why the workflow is waiting is the last non-bookkeeping event — the scheduling event (e.g., ActivityTaskScheduled, StartChildWorkflowExecutionInitiated, TimerStarted, NexusOperationScheduled) with no matching terminal event yet.

Asymmetric recording: per the event encyclopedia, "While the Activity is running and retrying, ActivityTaskScheduled is the only Activity-related Event in History: ActivityTaskStarted is written along with a terminal Event like ActivityTaskCompleted or ActivityTaskFailed." So a long gap between ActivityTaskScheduled and its terminal event does not imply the Activity is unpicked — it may be running and retrying. Use temporal workflow describe's Pending Activities section to see retry state, not the Event History alone.

Pending activities

A Pending Activity is an Activity whose ActivityTaskScheduled event has been appended but whose terminal event has not. The retry state of the in-flight Activity Execution (attempt count, last failure, paused status) is only visible via temporal workflow describe; it is not re-written to Event History on each retry.

Fields surfaced by describe for a pending activity

Docs state that describe surfaces "the current state of each pending Activity, including whether it's Paused, its current attempt count, and last failure." A Pending Activity block's exact text-output field names are not enumerated in a single docs location in this repo's snapshot. Treat the fields below as conceptual checkpoints for the diagnosis, and read the live describe output for exact field names.

Things to check on a pending activity:

  • Attempt count. If retries are climbing and the Activity has a Retry Policy with a finite Maximum Attempts, the Activity will eventually be recorded as ActivityTaskFailed and the Workflow will proceed (or fail) accordingly. If Maximum Attempts is unlimited and each attempt is failing for the same reason, the Workflow will loop indefinitely on this Activity.

  • Last failure. The last_failure field of ActivityTaskStarted carries "Details from the most recent failure Event. Only assigned values if the Task has previously failed and been retried." The describe output exposes the equivalent information for pending activities.

  • Scheduled vs. Started. If the Activity has never been picked up (only ActivityTaskScheduled in the history, no retry attempts in the pending block), the problem is almost certainly worker-side — no Worker is polling the Task Queue the Activity was scheduled on, or pollers exist but none match the Build ID routing the Workflow expects. Route to worker-health.md.

  • Timeouts on the scheduling attributes. The activityTaskScheduledEventAttributes record includes schedule_to_close_timeout, schedule_to_start_timeout, start_to_close_timeout, and heartbeat_timeout. A long-running Activity without heartbeats and a missing start_to_close_timeout or heartbeat_timeout can block indefinitely: "The Temporal Server doesn't detect failures when a Worker loses communication with the Server or crashes. Therefore, the Temporal Server relies on the Start-To-Close Timeout to force Activity retries."

  • Paused state. If the Activity was explicitly paused via temporal activity pause, retries are server-side suspended. Unpause via temporal activity unpause.

Heartbeating

For long-running activities, heartbeating is the only mechanism by which the server detects a dead worker. A missed heartbeat within the heartbeat_timeout results in ActivityTaskTimedOut and a retry. Activities without heartbeating cannot be killed server-side mid-execution; they run until start_to_close_timeout (or forever, if neither start-to-close nor schedule-to-close is set).

Pending child workflows

A Pending Child is one whose StartChildWorkflowExecutionInitiated or ChildWorkflowExecutionStarted event has been appended but whose terminal event (ChildWorkflowExecutionCompleted, ChildWorkflowExecutionFailed, ChildWorkflowExecutionCanceled, ChildWorkflowExecutionTimedOut, ChildWorkflowExecutionTerminated) has not.

Things to check:

  • Extract the child's Workflow ID and Run ID from the parent's describe output, then recurse into describe on the child. The parent is only stuck in the sense that the child is — the root cause lives in the child's describe / history.

  • The child may be in a different Namespace. Child Workflows can cross Namespaces; if the parent's describe shows a child that doesn't appear in the current Namespace's temporal workflow list, re-run describe with the correct --namespace.

  • Parent Close Policy. When a parent closes, Temporal "propagates Cancellation Requests or Terminations to Child Workflow Executions depending on the Child's Parent Close Policy." A child that is stuck because its parent was terminated but used the Abandon close policy is a different shape — the child is independently running.

Pending signals, cancellations, and updates

A Workflow's handling of Signals and Updates is Workflow-code-directed — the SDK's await / workflow.wait_condition APIs block the workflow until the condition becomes true. "Pending Signals" (server-side) are distinct from "Signals the Workflow is waiting for" (SDK / code-side):

  • SignalExternalWorkflowExecutionInitiated is an Event type recorded when this Workflow signals another. The terminal events are ExternalWorkflowExecutionSignaled (success) and SignalExternalWorkflowExecutionFailed. A stalled outgoing signal is a pending operation from the caller's perspective.

  • WorkflowExecutionSignaled is the Event type recorded when an external party (client, another Workflow, temporal workflow signal) sends a signal to this Workflow. If a Workflow is blocked waiting on a signal that has never been sent, no WorkflowExecutionSignaled event will appear — absence of the event is the symptom.

  • WorkflowExecutionUpdateAcceptedEvent / WorkflowExecutionUpdateCompletedEvent record Update lifecycle. A pending Update (accepted but not completed) keeps the Workflow responsible for resolving it.

Things to check for "waiting on a signal" stuck-ness:

  • Inspect the call stack. temporal workflow stack runs the __stack_trace Query and returns "a stack trace of the threads and routines currently in use by the Workflow for troubleshooting." This works only when a Worker is running and available to respond to queries. The stack trace will show which await or wait_condition the Workflow is blocked on, which identifies the signal/update name.

  • Send a test signal to confirm the handler is wired correctly: temporal workflow signal --workflow-id YourWorkflowId --name YourSignal --input '{"key": "value"}'.

  • Check the sender side. If the signal is being sent but not received, three app-code patterns account for most cases. All three are diagnosable from describe/show output:

    1. Stale Run ID after Continue-As-New. The sender targets a specific Run ID that belongs to a now-closed run (status ContinuedAsNew). The server accepts the signal — it is valid for the closed run — but the new run never sees it because it has a different Run ID. Symptom: WorkflowExecutionSignaled appears in the old run's history but not the current run's. Fix: the sender should omit the Run ID (letting the server route to the latest run in the chain) or re-resolve the Workflow ID to the current Run ID before signaling.

    2. Continue-As-New fires before in-flight handlers finish. The Workflow calls Continue-As-New without waiting for all_handlers_finished (Python) / the SDK-equivalent guard. In-flight signal and update handlers on the closing run are silently dropped — they never run to completion, and the new run has no record of them. Symptom: the sender sees success (the signal was delivered), but the Workflow behaves as if the signal never arrived. The old run's history shows WorkflowExecutionSignaled followed by WorkflowExecutionContinuedAsNew with no evidence the handler acted. Fix: the Workflow must await the all-handlers-finished condition before issuing Continue-As-New.

    3. Handler name mismatch. The sender uses a signal name that doesn't match any registered handler (e.g., order_shipped vs. orderShipped). The server accepts the signal — it does not validate handler names — so WorkflowExecutionSignaled appears in history, but no handler runs. The Workflow blocks forever on a condition that will never be satisfied. Symptom: history contains the WorkflowExecutionSignaled event with the signal name, but temporal workflow stack shows the Workflow still blocked on the same wait_condition. Fix: align the signal name in the sender with the name registered in the Workflow Definition.

The workflow has per-Workflow-Execution pending-signal limits documented in Pending-operation per-Workflow limits.

Pending Nexus Operations

A pending Nexus Operation is a Nexus call issued from this Workflow that has been scheduled (NexusOperationScheduled) and may have been started (NexusOperationStarted) but has not reached a terminal event (NexusOperationCompleted, NexusOperationFailed, NexusOperationTimedOut, NexusOperationCanceled).

temporal workflow describe surfaces pending Nexus Operations with these fields (from the docs' own example): Endpoint, Service, Operation, OperationToken, State, Attempt, ScheduleToCloseTimeout, NextAttemptScheduleTime, LastAttemptCompleteTime, LastAttemptFailure, and — when the per-destination circuit breaker is open — BlockedReason.

Things to check:

  • State. The docs' two text examples show BackingOff (retrying after a retryable error) and Blocked (circuit breaker open for the destination pair). Blocked with a BlockedReason of "The circuit breaker is open" means the handler side (or the network path to it) has produced enough consecutive timeouts / retryable errors to trip the breaker; handler Workers must recover before pending Operations resume.

  • LastAttemptFailure. Non-retryable errors resolve the Operation with a NexusOperationFailed / NexusOperationTimedOut / NexusOperationCanceled event. Retryable errors surface in the pending Operation with LastAttemptFailure filled in.

  • Pending Callbacks. Separate from Pending Operations, Nexus completion callbacks have their own pending view, surfaced as Callbacks: N with URL, Trigger, State, Attempt, RegistrationTime.

Pending Workflow Task and WorkflowTaskFailed loops

A Pending Workflow Task is a Workflow Task scheduled for this Workflow but not yet completed by a Worker. The JSON describe example shows the shape: pendingWorkflowTask.state, pendingWorkflowTask.scheduledTime, pendingWorkflowTask.originalScheduledTime, pendingWorkflowTask.attempt.

Distinguishing pending Workflow Task shapes
  • pendingWorkflowTask.attempt = 1, recently scheduled, no WorkflowTaskFailed in history. A Worker has not yet picked up the task. If this persists, route to worker-health.md: confirm pollers on the Workflow Task Queue.

  • pendingWorkflowTask.attempt > 1 and the Event History contains repeating WorkflowTaskFailed events. The task is being retried server-side after worker-reported failures.

  • pendingWorkflowTask absent while history has a recent WorkflowTaskCompleted. The last Workflow Task completed cleanly — the Workflow is not blocked on running Workflow code, it is blocked on an awaitable from that completed task (Activity, Child, Signal, Update, Timer, Nexus).

The WorkflowTaskFailed retry loop

WorkflowTaskFailed "indicates that the Workflow Task encountered a failure." The event's workflow_task_failed_event_attributes include scheduled_event_id, started_event_id, failure, identity, and (for Reset-initiated failures) base_run_id, new_run_id, fork_event_version, and binary_checksum. The failure field carries the detail of the failure.

Each WorkflowTaskFailed corresponds to a value of the WorkflowTaskFailedCause enum (referenced in Event attributes as cause). The error reference enumerates the causes; these are the ones relevant to stuck-ness:

Cause (in the errors.mdx reference)InterpretationRoute
Nondeterminism ErrorReplay diverged from recorded historynon-determinism.md
Workflow Worker Unhandled FailureAn unhandled failure (panic, exception) from the Workflow DefinitionWorker logs for stack trace; fix and redeploy
Unhandled CommandThe Workflow attempted to close without handling new Events; can occur under Signal loadDrain signal channel; inspect Worker logs
Pending Activities Limit ExceededWorkflow reached the per-Workflow pending-Activity capPending-operation per-Workflow limits
Pending Child Workflows Limit ExceededReached pending-Child capSame as above
Pending Signals Limit ExceededReached pending external-Signal capSame as above
Pending Nexus Operations Limit ExceededReached pending Nexus Operation capSame as above
Bad Search AttributesInvalid Search Attributes cause Workflow Tasks "to continue to retry without success."Fix Workflow code or attribute definitions
Detecting WFT-failure loops at scale with Task Issue detection

Rather than inspecting individual Workflows, use the TemporalReportedIssue search attribute to find all Workflows currently experiencing Workflow Task failures:

temporal workflow list \
    --query "TemporalReportedIssue IS NOT NULL" \
    --namespace <ns>

The TemporalReportedIssue search attribute is automatically set by the server when it detects a Workflow Task issue (e.g., repeated WorkflowTaskFailed events). This surfaces problems proactively without needing to inspect each Workflow individually.

Why a Workflow stays Running through WFT-failure loops

Workflow Tasks do not fail the Workflow Execution. The server retries failed Workflow Tasks so that once the Worker code is fixed and redeployed, the Workflow resumes. This is by design: the Event History is durable, and a bad deploy that causes a WFT to fail can be rolled back or patched without losing the Workflow's progress. The visible effect is that the Workflow stays Running, the Event History grows a tail of WorkflowTaskFailed events, and the attempt count climbs.

Timer-based waits

Timers are persisted server-side: "even if your Worker or Temporal Service is down when the time period completes, as soon as your Worker and Temporal Service become available, the call that is awaiting the Timer in your Workflow code will resolve." A Workflow that is waiting on a timer is not stuck; it is asleep. Fire time is deterministic from history.

The TimerStarted event carries timer_id, start_to_fire_timeout, and workflow_task_completed_event_id. The fire time is the eventTime of the TimerStarted event plus start_to_fire_timeout. If that fire time is in the future, the Workflow is working as designed; report the resume time rather than treating the Workflow as stuck.

"The duration of a Timer is fixed, and your Workflow might specify a value as short as one second or as long as several years." Multi-year timer waits are legitimate.

The terminal events are TimerFired (with timer_id and started_event_id) and TimerCanceled.

Pending-operation per-Workflow limits

The server enforces per-Workflow caps on the number of incomplete operations of each kind. Exceeding a cap fails the Workflow Task that attempted to add another operation of that kind — the Workflow Execution does not close, but the WFT will fail and retry until the pending count drains.

OperationDefault limitSource
Pending Activities2,000
Pending Child Workflow Executions2,000
Pending Signals (external)2,000
Pending Cancel Requests2,000
Pending Nexus Operations30

The Event-History caps are a separate ceiling that terminates the Workflow when crossed: "The Workflow Execution is terminated when the Event History exceeds 51,200 Events, contains more than 2000 Updates, or contains more than 10000 Signals." A stuck-looking Workflow approaching these limits will not stay Running — it will close with Terminated when it crosses them.

Recovery commands

These commands alter the Workflow's state or flow. Use them once the diagnosis identifies the shape of the stuck-ness.

temporal workflow signal

Send a Signal to unblock a Workflow that is waiting on one.

temporal workflow signal \
    --workflow-id YourWorkflowId \
    --name YourSignal \
    --input '{"key": "value"}'
temporal workflow terminate

Terminate a Workflow that cannot be recovered. Terminal events become the closing event of the Execution History. "Workflow code cannot see or respond to terminations. To perform clean-up work in your Workflow code, use temporal workflow cancel instead."

temporal workflow terminate \
    --workflow-id YourWorkflowId \
    --reason YourReason
temporal workflow cancel

Request cancellation. A WorkflowExecutionCancelRequested event is appended, and the Workflow runs any cleanup paths its code supports.

temporal workflow cancel \
    --workflow-id YourWorkflowId
temporal workflow reset

Reset the Workflow to a point in its Event History so it can resume from there without losing progress up to that point. Valid reset points per the Event encyclopedia are "WorkflowTaskStarted, WorkflowTaskCompleted, WorkflowTaskTimedOut, and WorkflowTaskFailed." A Reset terminates the current Run and creates a new Run with history copied up to the reset point.

temporal workflow reset \
    --workflow-id YourWorkflowId \
    --event-id YourLastEvent

To reset to where the current Run continued-as-new:

temporal workflow reset \
    --workflow-id YourWorkflowId \
    --type LastContinuedAsNew

The --type flag's LastContinuedAsNew value appears in the reset example. The batch-reset guidance in the same section mentions FirstWorkflowTask, LastWorkflowTask, and BuildId as the only --type values permitted for batch resets. A companion flag --reapply-type controls which Events are reapplied after the reset point; accepted values are Signal, None.

Because the new Run replays history only up to the reset point, everything after it happens again — Activities with external side effects re-execute, so a reset past a payment, an email, a provisioning call, or a non-idempotent write performs it a second time. --reapply-type None suppresses Signal reapplication; it does not prevent Activity re-execution. Establish where the side effects are relative to the candidate reset point, say so in the proposal, and prefer the latest reset point that still clears the problem.

temporal workflow pause / unpause

Experimental.

temporal workflow pause --workflow-id YourWorkflowId --reason YourReason
temporal workflow unpause --workflow-id YourWorkflowId --reason YourReason
temporal activity pause / unpause / reset

For stuck pending activities, Activity Operations are the surgical tool: pause to stop retries, unpause to resume, reset to clear attempt state. These operations are in Public Preview (Server v1.28.0+). Activity Operations don't produce Event History events — they leave no audit trail beyond the current describe output.

Quick routing

EvidenceGo to
workflowExecutionInfo.status is not RunningWorkflow Execution Status values — the workflow is Closed, not stuck
Pending activity present, no attempts yet, Event History shows ActivityTaskScheduled onlyworker-health.md — check pollers on the Activity's Task Queue
Pending activity present, attempts climbing, LastAttemptFailure reportedPending activities
Pending child workflow presentPending child workflows — recurse into the child
Waiting on a signal that never arrivesPending signals, cancellations, and updates; use temporal workflow stack
Pending Nexus Operation with State: Blocked or BackingOffPending Nexus Operations
pendingWorkflowTask.attempt > 1, WorkflowTaskFailed events accumulatingPending Workflow Task and WorkflowTaskFailed loops
TemporalReportedIssue search attribute set on Workflow(s)Detecting WFT-failure loops at scale
WFT failure cause is NonDeterministicErrornon-determinism.md
Last non-bookkeeping event is TimerStarted, fire time is in the futureTimer-based waits — not stuck
WFT fails with Pending Activities Limit Exceeded / Pending Child Workflows Limit Exceeded / Pending Signals Limit Exceeded / Pending Nexus Operations Limit ExceededPending-operation per-Workflow limits
Need to reproduce the failure locally under a debuggerreplay.md
temporal workflow describe itself fails (cannot reach / authenticate / authorize)connectivity.md, certificates.md, authentication.md, rate-limits.md

See the whole-stack picture in diagnostic-ladder.md.

Requirements and compatibility

Written for: OpenAI Codex, Claude Code

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Claude Code frontmatter, Needs an API key

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Temporal
Publisher
OpenAI (Official)
Distributed by
OpenAI
Source
openai/plugins · plugins/temporal/skills/temporal-ops · commit d420d13
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from plugins/temporal/LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Temporal or OpenAI.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download temporal-ops.zip