> 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/harness-platform/use-harness-platform/variables-and-expressions/customize-pipeline-run-form.md).

# Customize the pipeline run form

Give runtime input variables friendly labels, hide them conditionally, and restrict their allowed values based on other runtime variables.

{% hint style="info" %}
This feature is in Beta[^1] and requires enablement. [View all early access features.](/release-notes/features.md)

{% @harness-feature-flag-access/request-feature-flag-access module="platform" pagePath="platform/use-harness-platform/variables-and-expressions/customize-pipeline-run-form" featureFlags="%5B%7B%22name%22%3A%22Customize%20pipeline%20run%20form%22%2C%22key%22%3A%22PIPE\_RUNTIME\_INPUT\_CONFIG%22%2C%22status%22%3A%22BETA%22%2C%22description%22%3A%22Lets%20pipeline%20authors%20give%20runtime%20input%20variables%20friendly%20labels%20and%20descriptions%2C%20hide%20them%20conditionally%2C%20and%20restrict%20their%20allowed%20values%20based%20on%20other%20runtime%20input%20variables.%22%7D%5D" %}
{% endhint %}

The run form allows users to provide runtime input values before executing a pipeline. When a pipeline has many [runtime inputs](/harness-platform/use-harness-platform/variables-and-expressions/runtime-inputs.md), the form can become lengthy and difficult to navigate. Run form configuration enables pipeline authors to organize and streamline the inputs, creating a simpler, clearer, and more intuitive experience for everyone who runs the pipeline.

## What you will learn from this topic

* A friendly [label and description](#give-a-field-a-label-and-description) for a runtime input variable.
* Conditional [hiding of a field](#hide-a-field-conditionally) until another input has a specific value.
* [Restricted allowed values](#restrict-the-allowed-values-of-a-field) for a field, based on another input.
* [Condition syntax](#write-conditions), including combining conditions with `and`, `or`, and `not`.
* [Target paths](#find-the-target-path-for-a-variable) for a pipeline, stage, or template variable.
* [Pipeline execution behavior](#pipeline-execution-behavior) and [save-time validation](#save-time-validation) for a pipeline, trigger, or input set.

## Before you begin

Review the following before you configure the run form.

* **Runtime inputs**: Review [fixed values, runtime inputs, and expressions](/harness-platform/use-harness-platform/variables-and-expressions/runtime-inputs.md) to understand how a setting becomes a runtime input (`<+input>`).
* **Feature flag**: This feature requires the `PIPE_RUNTIME_INPUT_CONFIG` feature flag. Contact [Harness Support](mailto:support@harness.io) to enable it.

## Add a runtimeInputConfig entry

You add run form configuration once, per pipeline. Configure it from the Pipeline Studio, either visually or by editing the pipeline YAML directly. People who run the pipeline do not need to do anything.

{% tabs %}
{% tab title="Visual" %}
Save the pipeline, and select **Configure Run Form** from the icon rail on the right. Harness lists every variable that can be configured, grouped under **Pipeline Variables** or the matching stage group.

![The Configure Run Form panel, listing pipeline variables with Visible when and Allowed values when fields](https://173309742-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3F2TpHXhur2QtQnORSM9%2Fuploads%2Fgit-blob-3a0445fa130148acfecaaefb8b4a638631a76fa0%2Fconfigure-run-form-panel.png?alt=media)

Select a variable, then select the edit (pencil) icon to configure it. Enter a **Label** and **Description** for the run form. To show the field only under certain conditions, select **+ Add condition** under **Visible when**. To restrict the values allowed for the field, select **+ Add allowed values rule** under **Allowed values when**.

For **Visible when**, and for each allowed-values rule, set **Condition type** to **Comparison** to compare one field against a value using the **Operator** dropdown (**Equals**, **Not equals**, **In**, **Not in**, **Is empty**, **Is not empty**), or set it to **And**, **Or**, or **Not** to combine conditions.

For an allowed-values rule, add one or more conditions, then enter the **Allowed values** for when those conditions are true. Select **+ Add allowed values rule** to add another rule.

Select **Apply Changes**, and save the pipeline. The visual editor writes the same `runtimeInputConfig` entry described in the YAML tab.
{% endtab %}

{% tab title="YAML" %}
Switch to the **YAML** tab, and add a `runtimeInputConfig` list directly under `pipeline:`, at the same level as `variables:`:

```yaml
pipeline:
  variables:
    - name: pipelinevariable1
      type: String
      value: <+input>
    - name: pipelinevariable2
      type: String
      value: <+input>
  runtimeInputConfig:
    - target: pipeline.variables.pipelinevariable1
      label: Variable p1
    - target: pipeline.variables.pipelinevariable2
      label: Variable p2
      visibleWhen:
        field: pipeline.variables.pipelinevariable1
        op: isNotEmpty
      allowedValuesWhen:
        rules:
          - condition:
              field: pipeline.variables.pipelinevariable1
              op: eq
              value: a
            values:
              - b
              - c
```

In this example, `pipelinevariable2` is shown only when `pipelinevariable1` has a value, and if `pipelinevariable1` is `a`, `pipelinevariable2` can only be set to `b` or `c`.
{% endtab %}
{% endtabs %}

Only a `variable` that is set to `<+input>` can be configured. Add one entry to `runtimeInputConfig` for each field you want to customize. Each entry supports the following fields.

| Field               | Required | What it does                                                                                                                               |
| ------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `target`            | Yes      | The variable you are customizing. For more information, go to [Find the target path for a variable](#find-the-target-path-for-a-variable). |
| `label`             | No       | The friendly name shown on the run form.                                                                                                   |
| `description`       | No       | A short hint shown with the field.                                                                                                         |
| `visibleWhen`       | No       | A condition. The field is shown only when the condition is true. Without this field, the field is always shown.                            |
| `allowedValuesWhen` | No       | A list of rules. Each rule has a condition and the values allowed when that condition is true.                                             |

Add only the fields you need. A variable can have only one `runtimeInputConfig` entry.

### Give a field a label and description

The following example shows `region` labeled **Which region?** with a hint:

```yaml
pipeline:
  variables:
    - name: region
      type: String
      value: <+input>
  runtimeInputConfig:
    - target: pipeline.variables.region
      label: Which region?
      description: Pick where to deploy
```

### Hide a field conditionally

The following example shows the `approverEmail` field only when `environment` is `Prod`:

```yaml
pipeline:
  variables:
    - name: environment
      type: String
      value: <+input>
    - name: approverEmail
      type: String
      value: <+input>
  runtimeInputConfig:
    - target: pipeline.variables.approverEmail
      label: Approver email
      visibleWhen:
        field: pipeline.variables.environment
        op: eq
        value: Prod
```

### Restrict the allowed values of a field

Each rule in `allowedValuesWhen` reads: when this condition is true, only these values are allowed.

```yaml
pipeline:
  variables:
    - name: environment
      type: String
      value: <+input>
    - name: region
      type: String
      value: <+input>
  runtimeInputConfig:
    - target: pipeline.variables.region
      allowedValuesWhen:
        rules:
          - condition:
              field: pipeline.variables.environment
              op: eq
              value: Dev
            values:
              - dev-east
              - dev-west
          - condition:
              field: pipeline.variables.environment
              op: eq
              value: Prod
            values:
              - prod-east
              - prod-west
```

Rules are checked in order. The first rule that matches is used. If no rule matches, there is no restriction and any value is allowed. Every rule must list at least one value. If a rule cannot be evaluated, for example because the data it depends on is not available, Harness skips the rule check.

## Write conditions

A condition looks at one field and compares it to a value. A condition has a `field`, an `op` (the comparison), and, for most comparisons, a `value`.

| Operator     | Meaning                  | Example            |
| ------------ | ------------------------ | ------------------ |
| `eq`         | Equals one value         | `value: Prod`      |
| `ne`         | Does not equal one value | `value: Prod`      |
| `in`         | Is one of a list         | `value: [Dev, QA]` |
| `notIn`      | Is not one of a list     | `value: [Dev, QA]` |
| `isEmpty`    | Has no value             | No `value` needed  |
| `isNotEmpty` | Has a value              | No `value` needed  |

Combine conditions using `and`, `or`, or `not`. The following example shows a field when `environment` is `Prod` or `Staging`, and `region` is not `prod-west`:

```yaml
visibleWhen:
  and:
    - or:
        - field: pipeline.variables.environment
          op: eq
          value: Prod
        - field: pipeline.variables.environment
          op: eq
          value: Staging
    - not:
        field: pipeline.variables.region
        op: eq
        value: prod-west
```

A condition can be nested up to 3 levels deep, and an `and` or `or` group can hold up to 5 conditions.

## Find the target path for a variable

The `target` field, and any condition `field`, is the fully qualified name (FQN) path of the variable.

| Where the variable lives                                      | Path                                                              |
| ------------------------------------------------------------- | ----------------------------------------------------------------- |
| Pipeline variable                                             | `pipeline.variables.region`                                       |
| Stage variable (stage identifier `deploy`)                    | `pipeline.stages.deploy.variables.region`                         |
| Pipeline variable, when the pipeline uses a pipeline template | `pipeline.template.templateInputs.variables.region`               |
| Stage variable, when the stage uses a stage template          | `pipeline.stages.deploy.template.templateInputs.variables.region` |

## Important notes

Keep the following constraints in mind when you configure the run form.

* The `target` field, and every condition `field`, must be a runtime input (`<+input>`) of the pipeline.
* Only pipeline and stage `variables` can be configured, along with step environment variables. Inputs that belong to a service, environment, or infrastructure cannot be configured.
* Run form configuration cannot customize a non-variable runtime input, such as a looping strategy, conditional execution, a failure strategy, or a delegate selector.
* A secret variable cannot be used in a condition.
* Two fields cannot depend on each other in a loop. For example, field A cannot be shown only when field B is set if field B is also shown only when field A is set.
* For a `Number` variable, use numbers in `value` and in `values`.
* Run form configuration changes how an existing input is shown. It does not add new inputs.
* Run form configuration is optional. A pipeline without a `runtimeInputConfig` block works exactly as before.
* Run form configuration works for standard pipelines only. Unified (v1) pipelines are not supported.
* Run form configuration is retained when you move a pipeline to a different project or organization, or when you clone the pipeline.

## Pipeline execution behavior

This applies when you run, rerun, rerun from the last failed stage, or rerun from a specific stage.

The run form shows the friendly labels, hides fields that are not needed, and offers only the allowed values. Hiding a field only changes what appears on the run form. It does not stop anyone from running the pipeline with a different value.

The run form also offers an option to show every hidden field, for anyone who needs to set a value that is normally hidden. Revealing a hidden field does not change the allowed-value rules enforced for it.

{% hint style="warning" %}
**Allowed-value rules are always enforced.** If a run is started with a value that breaks a rule, the run does not start, whether the value comes from the run form, an input set, a trigger, or an API call. If Harness cannot resolve a value yet, for example because it is still an expression, the run is not blocked for that field.
{% endhint %}

The following example shows a message displayed when a run is blocked:

```
pipeline.variables.region: value [prod-east] is not one of [dev-east, dev-west] because pipeline.variables.environment is 'Dev'
```

## Save-time validation

Harness checks run form configuration at a different point for a pipeline, a trigger, and an input set.

### Save a pipeline

Harness checks the `runtimeInputConfig` block when you save the pipeline. If something is wrong, the save is blocked, and Harness lists every problem together so you can fix them in one pass. Every message starts with `Issue in the runtimeInputConfig.`.

| Message (shortened)                                                                                                                    | What to do                                                                                |
| -------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `"pipeline.variables.regon" is not a runtime input of this pipeline.`                                                                  | Check the spelling of the path, and make sure the variable value is `<+input>`.           |
| `... is not a configurable variable. Only variables can be configured.`                                                                | Pick a pipeline or stage variable instead.                                                |
| `... is targeted by more than one runtimeInputConfig entry.`                                                                           | Keep one entry per field, and merge the fields into that entry.                           |
| `This entry does not specify a target.`                                                                                                | Add a `target` to the entry.                                                              |
| `... is a secret and cannot be used in a condition.`                                                                                   | Use a non-secret variable in the condition.                                               |
| `Invalid operator "equals". Valid operators are: eq, ne, in, notIn, isEmpty, isNotEmpty.`                                              | Use one of the listed operators.                                                          |
| `The value given for operator "in" on ... has the wrong shape.`                                                                        | `eq`/`ne` take one value. `in`/`notIn` take a list. `isEmpty`/`isNotEmpty` take no value. |
| `This allowedValuesWhen rule for ... does not list any allowed values.`                                                                | Add at least one value to the rule.                                                       |
| `The value "abc" does not match the declared type of ...`                                                                              | Use a number for a `Number` variable.                                                     |
| `This condition is nested more than 3 level(s) deep.` or `This and block has 6 child condition(s), which is more than the limit of 5.` | Simplify the condition.                                                                   |
| `These entries depend on each other's visibility in a cycle.`                                                                          | Remove one of the dependencies.                                                           |

### Save a trigger

If a trigger uses fixed values for a pipeline that has run form configuration, the trigger's **Pipeline Input** tab offers only the allowed values for a restricted field, the same way the run form does. Harness also checks those values against the configuration when you save the trigger, and the trigger cannot be saved until you fix any value that breaks a rule.

![The Pipeline Input tab of a trigger, with a field restricted to the two values allowed by the matching rule](https://173309742-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3F2TpHXhur2QtQnORSM9%2Fuploads%2Fgit-blob-899d645ae7b4730cdcea6e83aec6354835187c54%2Ftrigger-pipeline-input-restricted-values.png?alt=media)

A trigger that uses an input set is not checked at save time. It is checked when the run starts.

### Save an input set

Saving an input set works exactly as it did before run form configuration. Run form configuration is not checked when you save an input set. It is checked later, when a pipeline run starts.

## Template refresh and reconciliation

Pipelines can use templates, and templates change over time. When you refresh a pipeline to pick up template changes, Harness keeps the `runtimeInputConfig` block in sync automatically.

Any entry or rule that no longer makes sense is removed, for example an entry for a variable that is no longer a runtime input, or a rule that depends on a variable that no longer exists. If every entry is still valid, nothing changes.

In rare cases, if the configuration cannot be repaired, Harness removes the whole `runtimeInputConfig` block so that the pipeline can still be saved and run. You can add the block again afterward. Review the refreshed pipeline before you save it.

## Complete pipeline YAML example

The following pipeline has three variables: `environment`, `region`, and `approverEmail`. Only some regions make sense for each environment, and the approver is needed only for `Prod`.

```yaml
pipeline:
  name: Deploy with approval
  identifier: deploy_with_approval
  projectIdentifier: myproject
  orgIdentifier: default
  tags: {}
  stages:
    - stage:
        name: Deploy
        identifier: Deploy
        description: ""
        type: Custom
        spec:
          execution:
            steps:
              - step:
                  type: ShellScript
                  name: Deploy
                  identifier: Deploy
                  spec:
                    shell: Bash
                    executionTarget: {}
                    source:
                      type: Inline
                      spec:
                        script: echo "Deploying to <+pipeline.variables.region>"
                    environmentVariables: []
                    outputVariables: []
                  timeout: 10m
        tags: {}
  variables:
    - name: environment
      type: String
      description: ""
      required: false
      value: <+input>
    - name: region
      type: String
      description: ""
      required: false
      value: <+input>
    - name: approverEmail
      type: String
      description: ""
      required: false
      value: <+input>
  runtimeInputConfig:
    - target: pipeline.variables.region
      label: Which region?
      description: Pick where to deploy
      allowedValuesWhen:
        rules:
          - condition:
              field: pipeline.variables.environment
              op: eq
              value: Dev
            values:
              - dev-east
              - dev-west
          - condition:
              field: pipeline.variables.environment
              op: eq
              value: Prod
            values:
              - prod-east
              - prod-west
    - target: pipeline.variables.approverEmail
      label: Approver email
      visibleWhen:
        field: pipeline.variables.environment
        op: eq
        value: Prod
```

With this configuration, the region field is labeled **Which region?** with the hint "Pick where to deploy." Choosing `Dev` shows only the two dev regions and no approver field. Choosing `Prod` shows only the two prod regions, plus the approver field. If someone tries to run the pipeline with `Dev` and `prod-east`, for example through an API call, the run is blocked with a clear message. If the pipeline author later removes the `region` input from a template, the matching entry is cleaned up on the next template refresh.

## Next steps

* [Fixed values, runtime inputs, and expressions](/harness-platform/use-harness-platform/variables-and-expressions/runtime-inputs.md): Review the other input types available for pipeline settings.
* [Use runtime input](/harness-platform/use-harness-platform/variables-and-expressions/runtime-input-usage.md): Set default values and allowed values for a runtime input.
* [Input sets and overlays](/harness-platform/use-harness-platform/pipelines/input-sets.md): Preconfigure sets of runtime input values.

[^1]: Off by default. If you want to try it and share feedback, request access and Harness will turn it on for your account. Beta features can change and may not be ready for production use.
