> ## Documentation Index
> Fetch the complete documentation index at: https://learn.workflow.dog/llms.txt
> Use this file to discover all available pages before exploring further.

# Project variables

> Persist values between workflow runs and share them across a project.

**Project variables** store values between workflow runs. Every workflow in the
same project can read or update a variable by its key.

Use project variables for state that must outlive one run, such as the last
processed identifier, a routing preference, or a list accumulated over time.

<Warning>
  Project variables are not secrets. Every project member with Viewer or Editor
  access can inspect their values from the dashboard. Do not store passwords,
  API keys, or access tokens in them.
</Warning>

## Set and read a value

<Steps>
  <Step title="Set the variable">
    Add [Set Project Variable](/reference/actions/core/set-project-var).
    Provide a **Key** and the **Value** to store. Setting an existing key
    replaces its previous value.
  </Step>

  <Step title="Read the variable">
    In the same or another workflow, add [Get Project
    Variable](/reference/actions/core/get-project-var) and use the exact same key.
  </Step>

  <Step title="Handle the missing case">
    Set **Default Value** when the workflow needs a fallback. Without a default, a
    missing variable returns `null`.
  </Step>

  <Step title="Inspect the result">
    Open **Variables** in the project dashboard to view the stored key, value,
    and last update time.
  </Step>
</Steps>

## Variable behavior

| Operation  | Existing key                                        | Missing key                    |
| ---------- | --------------------------------------------------- | ------------------------------ |
| **Set**    | Replaces the stored value.                          | Creates the variable.          |
| **Get**    | Returns the stored value with its WorkflowDog type. | Returns the default or `null`. |
| **Append** | Adds items when the current value is a list.        | Starts with an empty list.     |
| **Clear**  | Deletes the variable record.                        | Makes no change.               |

Keys are scoped to the project and matched exactly. `lastCustomerId` and
`LastCustomerId` are different variables.

The Variables dashboard search helps locate similar keys, but it does not
change exact key matching inside workflows.

## Append to a stored list

[Append to List in Project Variables](/reference/actions/core/append-to-project-var-list)
loads the current list, appends the supplied values in order, and stores the
combined list.

If the key does not exist, the action starts from `[]`. If the existing value
is not a list, the node reports **Value is not a list**. A value that can no
longer be decoded reports **Variable is corrupted**.

<Warning>
  Append reads the existing list and writes a replacement; it is not an atomic
  concurrent append. If parallel runs append to the same key at nearly the same
  time, both can read the same old list and the later write can overwrite the
  other run's additions. Serialize those writes or give parallel work separate
  keys.
</Warning>

## Inspect and clear variables

Open **Variables** from the project dashboard to:

* Search keys.
* Preview simple values.
* Expand lists and objects in the data navigator.
* See when a value was last updated.
* Choose **Clear Value** to delete a variable.

The dashboard does not create or edit values directly. Use workflow actions to
set or append values.

Clearing a variable deletes it rather than storing `null`. The next **Get
Project Variable** returns its configured default, or `null` if no default was
set.

## Example: remember the last processed item

1. Start the workflow with a schedule trigger.
2. Get the `last_processed_id` project variable.
3. Fetch and process items created after that ID.
4. Set `last_processed_id` to the newest successfully processed item.

Set the variable only after the workflow successfully processes the item you
want to mark. If a node earlier in the path errors and the Set node does not
run, the previous checkpoint remains available for the next run.

## Choose stable keys

Good keys state both the value and its purpose:

```text theme={null}
support_last_processed_message_id
daily_report_recipient
crm_pending_record_ids
```

Avoid reusing one key for unrelated data types. A key that sometimes contains
a number and sometimes a list makes downstream workflows harder to reason
about and can break list-specific actions.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Get Project Variable returns null">
    Confirm the key matches exactly, including capitalization and whitespace,
    and that the workflow is in the same project as the variable. Also check
    whether someone cleared the value from the Variables page.
  </Accordion>

  <Accordion title="Append says Value is not a list">
    The key currently contains another type. Inspect it on the Variables page,
    then clear it or use **Set Project Variable** to initialize it with a list.
  </Accordion>

  <Accordion title="Items disappear during parallel appends">
    Multiple runs are replacing the same list concurrently. Route updates through
    one sequential workflow, avoid parallel execution for that key, or store each
    run under a separate key.
  </Accordion>

  <Accordion title="I cannot edit a value from the dashboard">
    The dashboard is for inspection and clearing. Add **Set Project Variable**
    to a workflow to create or replace the value.
  </Accordion>
</AccordionGroup>
