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

# Input Validation

> Validate workflow run inputs with JSON Schema before execution

`input_schema` lets a workflow define the expected shape of run inputs using JSON Schema.

When enabled, Cyberdesk validates the **effective** input payload:

* `input_values`
* `sensitive_input_values`
* selected pool parameters (when pools are explicitly selected)
* machine/session-provided values (when available)

When multiple sources provide the same key, Cyberdesk uses run-level values first, then machine-provided defaults, then selected pool defaults. This includes explicit `__EMPTY__` values; omitted/null/blank keys still allow defaults to fill. `__CLEAR__` is preserved as a normal string during validation and later clears the field at typing time instead of being treated as omitted.

Sensitive inputs are exposed to schema validation with a `$`-prefixed root key.
For example, `sensitive_input_values.api_key` is available in schema as `$api_key`.

This also means input and sensitive values can share a base name without collision:

* input key: `customer_id`
* sensitive key in schema: `$customer_id`

This helps catch bad payloads early, before a run spends time on machine setup and execution.

## Why this exists

Input variables in prompts are flexible, but flexibility can hide mistakes:

* misspelled keys
* missing required fields
* wrong types (`"123"` vs `123`)
* malformed nested objects

`input_schema` makes these issues explicit and gives path-level errors.

## Where validation happens

Validation is intentionally hybrid:

1. **Dashboard preflight (client-side):**\
   As you prepare a run, the dashboard validates current inputs against the selected workflow's `input_schema` (when present).\
   When pools are selected, pool parameters are merged into preflight validation. When machine context is known (for example, selected machine or an existing session with a reserved machine), known machine parameters are merged too.\
   When machine context is not known yet (for example, auto/pool assignment), missing required root keys that may come from machine parameters are deferred, and strict checks continue later.

2. **API create-time (server-side):**\
   The API validates run payloads and returns structured `422` errors for schema failures.\
   When selected pools are known, pool-provided values are merged at create-time. When machine/session context is known, machine-provided values are merged and strict checks run at create-time.\
   When machine context is not known yet, Cyberdesk still validates concrete user-provided and selected-pool values immediately, but defers root-level missing `required` keys that may be satisfied by machine defaults after assignment.

3. **Execution-time strict validation (worker):**\
   Validation runs again after refs are resolved and execution context is fully known.

<Info>
  If a payload contains unresolved refs (`$ref`), full strict validation may be deferred until execution-time when those values are available.
</Info>

## Defining an input schema

Add `input_schema` on your workflow as a JSON Schema object:

```json theme={null}
{
  "type": "object",
  "required": ["accountId", "$apiKey"],
  "properties": {
    "accountId": {
      "type": ["string", "number", "boolean", "object", "array"]
    },
    "$apiKey": {
      "type": ["string", "number", "boolean", "object", "array"]
    },
    "amount": { "type": "number", "minimum": 0 },
    "customer": {
      "type": "object",
      "required": ["name"],
      "properties": {
        "name": { "type": "string" },
        "email": { "type": "string", "format": "email" }
      }
    }
  },
  "additionalProperties": true
}
```

By default in the dashboard:

* detected prompt input and sensitive variables are auto-added to `properties`
* all detected variables are added to `required`
* each auto-generated property defaults to `type: ["string", "number", "boolean", "object", "array"]`
* `additionalProperties` defaults to `true`
* structured prompt paths (for example `{$nested.variable.hi}`) auto-generate nested object/array schema shape with required path keys

`pattern` validation is fully supported for string schemas (for example `^\\d{2}-\\d{2}-\\d{4}$` for `MM-DD-YYYY`), and validation failures include path-level messages like `$.date: must match pattern ...`.

## Prompt-linked schema sync while editing

In the workflow editor, `input_schema` stays synced to prompt variables as you type.

* Sync is debounced while editing.
* On **Save**, Cyberdesk performs a final sync pass.
* If you customize constraints/descriptions, Cyberdesk preserves those edits and only updates variable **names/paths** when the prompt variable is renamed.
* Sensitive variables stay mapped to `$`-prefixed schema keys.

You can monitor this in the prompt toolbar:

* **Input Schema - Syncing…** while reconciliation is running
* **Input Schema - Synced** when complete

Hover the indicator to quickly review what the sync does and jump to the schema editor.

## Chains and refs

In chains, each step is validated against **that step's workflow** `input_schema`.

Validation uses the merged payload for each step:

* shared inputs + shared sensitive inputs
* step inputs + step sensitive inputs

Refs are supported:

```json theme={null}
{
  "customer": { "$ref": "step1.outputs.result.customer" }
}
```

### Ref validation behavior

Cyberdesk validates refs in layers:

1. **Create-time compatibility checks**
   * For chain refs to earlier steps in the same request, Cyberdesk validates the ref path/type against the producing step's `output_schema`.
   * For refs to existing runs in an existing session, Cyberdesk validates alias/path/type compatibility using available source metadata (`output_schema`, and concrete `output_data` types when present).
   * Create-time checks are intentionally permissive about **existence** when the source output may not be materialized yet (for example queued/scheduling runs in the same session).

2. **Execution-time strict checks**
   * After refs are resolved to concrete values, strict input schema validation runs again in the worker.
   * This is where required referenced values must actually exist.

This means a ref can pass create-time compatibility but still fail at execution if the referenced value is missing or resolves to the wrong concrete type.

Example:

* Producer `output_schema` allows `data` as optional / nullable.
* Consumer `input_schema` requires `data` as `string`.
* If producer's actual `output_data` omits `data` (or sets it to `null`), consumer run fails when refs are resolved/executed.

<Info>
  When refs are unresolved at create-time (for example future in-chain outputs), final strict validation still runs at execution-time after values are resolved.
</Info>

## Error format (422)

Schema validation errors return typed details so clients can render precise messages:

```json theme={null}
{
  "detail": {
    "message": "Input schema validation failed",
    "error_code": "INPUT_SCHEMA_VALIDATION_FAILED",
    "details": [
      {
        "path": "$.customer.email",
        "message": "must match format \"email\""
      }
    ]
  }
}
```

## Dashboard UX notes

* Workflow editor supports AI-assisted `input_schema` generation.
* Run creation validates both form and JSON input modes.
* Chain mode validates each step independently and reports step-scoped errors.

## Best practices

* Start with `type: object` + `required` for critical fields.
* Add constraints (`format`, `minimum`, enums) for high-signal validation.
* Keep schema close to prompt expectations.
* Use optional fields for truly optional inputs; avoid over-constraining.

<Tip>
  For nested prompt access patterns like `{customer.email}` or `{$credentials.token}`, pair this with [Structured Inputs](/concepts/structured-inputs).
</Tip>
