Master Temporal CLI workflow management with smart query building, payload decoding, and history filtering using temporal, base64, and jq
Execute Temporal CLI commands with smart patterns for workflow management. This skill provides comprehensive knowledge for using Temporal CLI v1.5.1 effectively with base64 and jq.
~/.config/temporalio/temporal.yamlALL Temporal CLI commands follow this base pattern:
temporal --env <environment> -o json --time-format iso workflow <operation> [args...]
Global flags (ALWAYS used):
--env <env> - Temporal environment from config-o json - JSON output format--time-format iso - ISO 8601 timestamps⚠️ PIPING CAVEAT: Direct piping from temporal to jq can fail with mysterious errors. Use one of these patterns instead:
# Option 1: Store in variable (for smaller outputs)
RESULT=$(temporal --env prod -o json workflow show -w "my-wf")
echo "$RESULT" | jq '...'
# Option 2: Write to file first (recommended for histories)
temporal --env prod -o json workflow show -w "my-wf" > /tmp/wf.json
jq '...' /tmp/wf.json
| Operation | Reference Guide | Use Case |
|---|---|---|
| list workflows | Command Patterns | Find workflows by query |
| count workflows | Command Patterns | Get result scope before listing |
| describe workflow | Command Patterns | Get current workflow state |
| show history | Command Patterns | View execution events |
| start workflow | Command Patterns | Create new execution |
| signal workflow | Command Patterns | Send signal to running workflow |
| query workflow | Command Patterns | Query workflow state |
| cancel workflow | Command Patterns | Request cancellation |
| terminate workflow | Command Patterns | Force termination |
| reset workflow | Command Patterns | Reset execution to previous point |
| stack trace | Command Patterns | Get workflow stack trace |
| Guide | Purpose |
|---|---|
| Query Construction | Complete query syntax with 50+ examples |
| Custom Search Attributes | Using custom fields in queries |
| Payload Decoding | Base64/jq recipes for history payloads |
| History Filtering | jq patterns for managing large histories |
| Smart Patterns | Count-first, auto-retry, validation logic |
| Error Handling | Common errors and recovery |
| Safety Checks | Validation for destructive operations |
When searching for workflows by type and you're unsure of the exact type name, always discover available workflow types first. Workflow type names in code (e.g., OnboardingWorkflow) may differ from the registered name in Temporal (e.g., PatientOnboarding).
# List recent workflows and extract unique workflow types
temporal --env prod -o json --time-format iso workflow list --limit 100 | \
jq -r '[.[].type.name] | unique | sort | .[]'
# Or find workflows with type names containing a keyword
temporal --env prod -o json --time-format iso workflow list --limit 200 | \
jq -r '[.[].type.name] | unique | .[] | select(test("onboard"; "i"))'
Why this matters:
handler.PatientOnboarding register as PatientOnboarding, not the struct/file name# Get count first to understand scope
COUNT=$(temporal --env prod -o json --time-format iso workflow count \
--query "ExecutionStatus = 'Failed'" | jq '.count')
# Then list with appropriate limit
temporal --env prod -o json --time-format iso workflow list \
--query "ExecutionStatus = 'Failed'" \
--limit ${COUNT}
Histories with 100+ events should be filtered:
# Use jq to show only failures
temporal --env prod -o json --time-format iso workflow show \
--workflow-id "my-workflow" | \
jq '.events[] | select(.eventType | contains("Failed"))'
See History Filtering for more patterns.
Pre-validate queries before execution to avoid errors:
# Check for unsupported LIKE operator
if echo "$QUERY" | grep -qi 'LIKE'; then
echo "ERROR: Use STARTS_WITH instead of LIKE"
exit 1
fi
See Smart Patterns for validation logic.
Workflow event payloads are base64-encoded:
# Decode workflow input
temporal --env prod -o json --time-format iso workflow show \
--workflow-id "my-workflow" | \
jq -r '.events[0].workflowExecutionStartedEventAttributes.input.payloads[0].data' | \
base64 -d | \
jq '.'
See Payload Decoding for complete recipes.
# Count failures
temporal --env prod -o json --time-format iso workflow count \
--query "ExecutionStatus = 'Failed'"
# List failed workflows
temporal --env prod -o json --time-format iso workflow list \
--query "ExecutionStatus = 'Failed'" \
--limit 10
IMPORTANT: Workflows with non-deterministic errors often remain in Running status, not Failed. Use TemporalReportedProblems to find them:
# Find running workflows with WorkflowTask failures (includes non-deterministic errors)
temporal --env prod -o json --time-format iso workflow list \
--query "ExecutionStatus = 'Running' AND TemporalReportedProblems IN ('category=WorkflowTaskFailed', 'category=WorkflowTaskTimedOut')" \
--limit 20
# Count problematic workflows
temporal --env prod -o json --time-format iso workflow count \
--query "ExecutionStatus = 'Running' AND TemporalReportedProblems IN ('category=WorkflowTaskFailed')"
TemporalReportedProblems values:
category=WorkflowTaskFailed - WorkflowTask failed (includes non-deterministic errors)category=WorkflowTaskTimedOut - WorkflowTask timed outcause=WorkflowTaskFailedCauseNonDeterministicError - Specifically non-deterministic errorsGet failure details from history:
# Get the last WorkflowTaskFailed event with full error message
temporal --env prod -o json --time-format iso workflow show \
--workflow-id "my-workflow" | \
jq '[.events[] | select(.eventType == "EVENT_TYPE_WORKFLOW_TASK_FAILED")] | .[-1]'
# Get stack trace
temporal --env prod -o json --time-format iso workflow stack \
--workflow-id "stuck-workflow-123"
# Check history for patterns
temporal --env prod -o json --time-format iso workflow show \
--workflow-id "stuck-workflow-123" | \
jq '[.events[] | .eventType] | group_by(.) | map({type: .[0], count: length})'
⚠️ CRITICAL: Activity retries are invisible in event history (workflow show). While an activity is retrying, the history only shows ACTIVITY_TASK_SCHEDULED — no STARTED/FAILED events until the final outcome. Use workflow describe → pendingActivities instead:
# See last failure, attempt count, and next retry time for all pending activities
temporal --env prod -o json workflow describe -w "stuck-workflow-123" | \
jq '.pendingActivities[] | {activityType: .activityType.name, attempt, state, lastFailure: .lastFailure.message, nextRetry: .nextAttemptScheduleTime}'
When to use this: Whenever workflow show reveals an ACTIVITY_TASK_SCHEDULED as the last event with no subsequent STARTED/COMPLETED/FAILED — the activity is retrying, and pendingActivities has the error.
# Using custom search attribute
temporal --env prod -o json --time-format iso workflow list \
--query "CustomerId = 'customer-abc-123'" \
--limit 20
Before destructive operations (terminate, reset):
--reasontemporal --env staging -o json --time-format iso workflow list \
--query "WorkflowType = 'OnboardingFlow'" \
--limit 10
temporal --env staging -o json --time-format iso workflow start \
--type "OnboardingFlow" \
--task-queue "patient-workflows" \
--workflow-id "patient-onboard-$(date +%s)" \
--input '{"customerId": "cust-123"}'
temporal --env prod -o json --time-format iso workflow signal \
--workflow-id "order-processing-456" \
--name "approvalReceived" \
--input '{"approved": true}'
Pre-built templates available in assets/:
query-templates.json - Common query patternsjq-filters.json - Reusable jq filtersevent-types.json - Event type referencetemporal --versioncat ~/.config/temporalio/temporal.yamltemporal --env staging -o json --time-format iso workflow countTemporalReportedProblems query (see above) or Error Handlingworkflow describe → pendingActivities (see "Investigate Stuck/Retrying Activities" above)Start with Command Patterns for complete bash examples of all operations.