> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/ai-sre/ai-sre-for-administrators/get-started/expression-languages.md).

# Create Your First Dynamic Content

Compare CEL and Mustache, the two expression languages Harness AI SRE uses for conditional logic versus simple variable substitution.

Harness AI SRE supports two expression languages for creating dynamic content: **CEL (Common Expression Language)** for logic and conditions, and **Mustache** for simple variable substitution.

### CEL versus Mustache <a href="#cel-versus-mustache" id="cel-versus-mustache"></a>

Choose the right expression language based on your needs:

| Feature          | CEL (`${{expression}}`)                           | Mustache (`{{variable}}`)         |
| ---------------- | ------------------------------------------------- | --------------------------------- |
| **Purpose**      | Logic and computation                             | Simple variable substitution      |
| **Use cases**    | Conditions, transformations, calculations         | Display values, basic templating  |
| **Capabilities** | Boolean logic, regex, math, functions             | Variable interpolation only       |
| **Syntax**       | `${{incident.severity == "0"}}`                   | `{{incident.severity}}`           |
| **Return types** | Any type (string, number, boolean, array, object) | String only                       |
| **Mixing**       | Cannot mix with Mustache in same field            | Cannot mix with CEL in same field |

***

### When to use each <a href="#when-to-use-each" id="when-to-use-each"></a>

#### Use CEL when you need: <a href="#use-cel-when-you-need" id="use-cel-when-you-need"></a>

* **Conditional logic:** Filter or route based on conditions.
* **Regex matching:** Pattern matching on service names or messages.
* **Calculations:** Math operations, thresholds, percentages.
* **Transformations:** String manipulation, datetime formatting.
* **Complex logic:** Multi-field boolean expressions.

#### Use Mustache when you need: <a href="#use-mustache-when-you-need" id="use-mustache-when-you-need"></a>

* **Simple display:** Show field values in messages.
* **Basic templating:** Insert variables into text.
* **Field mapping:** Map source fields to destination fields.
* **Static substitution:** Replace placeholders with values.

***

### Where to use CEL <a href="#where-to-use-cel" id="where-to-use-cel"></a>

CEL is available in these contexts:

#### 1. Alert rule conditions <a href="#id-1-alert-rule-conditions" id="id-1-alert-rule-conditions"></a>

Filter incoming alerts before creating incidents.

**Example:**

```cel
alert.severity == "critical" && alert.source.matches("prod-.*")
```

Go to [Use CEL in Route Alerts](/ai-sre/ai-sre-for-administrators/set-up-alert-management/alert-rules/use-cel-alert-rules.md) to filter alerts.

#### 2. Runbook trigger conditions <a href="#id-2-runbook-trigger-conditions" id="id-2-runbook-trigger-conditions"></a>

Control when runbooks automatically execute.

**Example:**

```cel
incident.severity == "0" && incident.environment == "production"
```

Go to [Use CEL in Runbook Triggers](/ai-sre/ai-sre-for-administrators/set-up-runbook-management/triggers/use-cel-triggers.md) to control runbook execution.

#### 3. Webhook advanced mapping conditions <a href="#id-3-webhook-advanced-mapping-conditions" id="id-3-webhook-advanced-mapping-conditions"></a>

Filter webhook payloads before creating alerts.

**Example:**

```cel
webhook.priority == "P1" && webhook.region.matches("us-.*")
```

Go to [Use CEL in Webhooks](/ai-sre/ai-sre-for-administrators/set-up-alert-management/webhooks/use-cel-webhooks.md) to filter webhook payloads.

#### 4. Runbook action fields (inline) <a href="#id-4-runbook-action-fields-inline" id="id-4-runbook-action-fields-inline"></a>

Embed CEL expressions in text fields for dynamic content.

**Example:**

```
Incident ${{incident.title}} has severity ${{incident.severity == "0" ? "CRITICAL" : "Normal"}}
```

Go to [Use CEL in Runbook Actions](/ai-sre/ai-sre-for-administrators/set-up-runbook-management/workflows/use-cel-runbook-actions.md) to embed expressions in action fields.

***

### Where to use Mustache <a href="#where-to-use-mustache" id="where-to-use-mustache"></a>

Mustache is available in these contexts:

#### 1. Runbook action fields <a href="#id-1-runbook-action-fields" id="id-1-runbook-action-fields"></a>

Insert field values into messages, tickets, and notifications.

**Example:**

```
Incident {{incident.title}} detected in {{incident.environment}}
```

Go to [Use Mustache in Runbook Actions](/ai-sre/ai-sre-for-administrators/set-up-runbook-management/workflows/use-mustache-runbook-actions.md) to insert field values into actions.

#### 2. Map webhook fields <a href="#id-2-map-webhook-fields" id="id-2-map-webhook-fields"></a>

Map webhook payload fields to alert properties.

**Example:**

```
{{webhook.alert.name}}
```

Go to [Use Mustache in Webhooks](/ai-sre/ai-sre-for-administrators/set-up-alert-management/webhooks/use-mustache-webhooks.md) to map payload fields to alerts.

***

### Harness-specific information <a href="#harness-specific-information" id="harness-specific-information"></a>

#### Feature flag <a href="#feature-flag" id="feature-flag"></a>

CEL expressions require the feature flag `IR_CEL_CONDITIONS`. Contact your Harness account team to enable this feature.

#### Expression limits <a href="#expression-limits" id="expression-limits"></a>

CEL and Mustache expressions have the following limits:

* **Max CEL expression length:** 4,096 characters
* **No mixing:** Cannot use both CEL and Mustache in the same field
* **No preview:** Expressions cannot be tested before execution

#### Harness-specific data <a href="#harness-specific-data" id="harness-specific-data"></a>

**Severity values** are strings, not numbers:

```cel
// ✅ Correct
incident.severity == "0"

// ❌ Wrong - comparing string to number
incident.severity == 0
```

**Timestamps** are milliseconds since Unix epoch:

```cel
incident.created_at > 1704067200000
```

***

### Common patterns <a href="#common-patterns" id="common-patterns"></a>

#### Severity checks <a href="#severity-checks" id="severity-checks"></a>

**Single severity:**

```cel
incident.severity == "0"    // SEV0 (Critical)
```

**Multiple severities:**

```cel
incident.severity in ["0", "1", "2"]
```

#### String operations <a href="#string-operations" id="string-operations"></a>

**Contains check:**

```cel
incident.title.contains("database")
```

**Regex matching:**

```cel
incident.service.matches("^payment-.*")
```

**Regex extraction:**

```cel
regex.extract(Webhook.parsed_body, r"\"AlarmName\"\:\"(.*)\"")
```

**Case conversion:**

```cel
incident.environment.upperAscii()
```

**String trimming:**

```cel
incident.title.trim()
```

**Replace text:**

```cel
regex.replace(incident.description, r"\n", ", ")
```

#### Null safety and default values <a href="#null-safety-and-default-values" id="null-safety-and-default-values"></a>

**Always check for null:**

```cel
// ✅ Safe
incident.owner != null && incident.owner.contains("@example.com")

// ❌ May fail if owner is null
incident.owner.contains("@example.com")
```

**Provide default values with orValue():**

```cel
// Returns "Unknown" if field is null or empty
regex.extract(Webhook.parsed_body, r"\"AlarmName\"\:\"(.*)\"").orValue("")

// Chain multiple operations with safe defaults
incident.owner.orValue("Unassigned").trim()
```

#### Mustache nested fields <a href="#mustache-nested-fields" id="mustache-nested-fields"></a>

**Access nested data:**

```
{{webhook.metadata.environment}}
{{alert.resource.name}}
```

#### Collection operations <a href="#collection-operations" id="collection-operations"></a>

CEL provides powerful collection operations for working with arrays and lists.

**Get collection size:**

```cel
size(incident.affected_services) > 3
```

**Check if any item matches:**

```cel
incident.tags.exists(t, t == "customer-impact")
```

**Extract Harness service IDs from impacted services:**

```cel
Activity.impacted_services.map(s, s.id)
// Returns: ["9280f15c-8c59-4c32-834b-3b36c06d269b", "a1b2c3d4-..."]
```

**Get first service ID:**

```cel
Activity.impacted_services[0].id
```

**Filter services by name pattern:**

```cel
Activity.impacted_services.filter(s, s.name.contains("api"))
```

**Count services matching a condition:**

```cel
size(Activity.impacted_services.filter(s, s.name.contains("api")))
```

**Combine operations:**

```cel
// Get IDs of all API services
Activity.impacted_services
  .filter(s, s.name.contains("api"))
  .map(s, s.id)
```

{% hint style="info" %}
**ACTIVITY NAMESPACE**

`Activity.*` provides access to incident and activity data in runbook action fields. Use `Activity.impacted_services` to get the list of Harness services affected by an incident, not just service names.
{% endhint %}

***

### Examples <a href="#examples" id="examples"></a>

#### CEL: dynamic Slack message <a href="#cel-dynamic-slack-message" id="cel-dynamic-slack-message"></a>

```
${{incident.severity == "0" ? "[CRITICAL]" : "[ALERT]"}}
**Service**: ${{incident.service}}
**Environment**: ${{incident.environment}}
**Status**: ${{incident.status}}

${{incident.severity in ["0", "1"] ?
  "**IMMEDIATE ACTION REQUIRED**" :
  "Monitor and triage as needed"}}

View: ${{incident.url}}
```

#### Mustache: simple Jira ticket <a href="#mustache-simple-jira-ticket" id="mustache-simple-jira-ticket"></a>

```
**Incident**: {{incident.short_id}}
**Title**: {{incident.title}}
**Service**: {{incident.service}}
**Environment**: {{incident.environment}}
**Severity**: SEV{{incident.severity}}

Link: {{incident.url}}
```

***

### Related concepts <a href="#related-concepts" id="related-concepts"></a>

#### CEL language reference <a href="#cel-language-reference" id="cel-language-reference"></a>

* Go to [cel.dev](https://cel.dev/) to read the official CEL documentation.
* Go to the [CEL language definition](https://github.com/google/cel-spec/blob/master/doc/langdef.md) to review the complete syntax reference.

#### Harness AI SRE guides <a href="#harness-ai-sre-guides" id="harness-ai-sre-guides"></a>

* [Use CEL in Route Alerts](/ai-sre/ai-sre-for-administrators/set-up-alert-management/alert-rules/use-cel-alert-rules.md)
* [Use CEL in Runbook Triggers](/ai-sre/ai-sre-for-administrators/set-up-runbook-management/triggers/use-cel-triggers.md)
* [Use CEL in Webhooks](/ai-sre/ai-sre-for-administrators/set-up-alert-management/webhooks/use-cel-webhooks.md)
* [Use CEL in Runbook Actions](/ai-sre/ai-sre-for-administrators/set-up-runbook-management/workflows/use-cel-runbook-actions.md)
* [Use Mustache in Runbook Actions](/ai-sre/ai-sre-for-administrators/set-up-runbook-management/workflows/use-mustache-runbook-actions.md)
* [Use Mustache in Webhooks](/ai-sre/ai-sre-for-administrators/set-up-alert-management/webhooks/use-mustache-webhooks.md)

{% @harness-feedback/feedback %}
