Skip to content

Variables Reference

Habits uses a powerful variable system to pass data between nodes, access request data, environment variables, and utility functions. Variables use the syntax and are resolved at runtime.

Variable Syntax

Variables are enclosed in double curly braces:

{{variable.path}}

Supports:

  • Dot notation: {{habits.input.userId}}
  • Nested access: {{previous-node.result.items.name}}
  • Array indexing: {{node-id.output.0.data}}

Variable Categories

Request Input (habits.input.*)

Access data from HTTP POST requests or CLI arguments.

VariableDescriptionExample
{{habits.input}}Full request body{"name": "John", "age": 30}
{{habits.input.fieldName}}Specific field from request (POST or GET){{habits.input.userId}}
{{habits.input.query}}Nested Params{{habits.input.query.page}}

HTTP Request Example:

bash
curl -X POST http://localhost:3000/api/my-workflow \
  -H "Content-Type: application/json" \
  -d '{"userId": "123", "action": "send"}'

In your workflow, access with:

  • {{habits.input.userId}}"123"
  • {{habits.input.action}}"send"

CLI Example:

bash
habits execute --config ./stack.yaml --id my-workflow --input '{"userId": "123"}'

HTTP Headers (habits.header.*)

Access HTTP request headers (case-insensitive).

VariableDescriptionExample
{{habits.header.authorization}}Authorization headerBearer token
{{habits.header.content-type}}Content typeapplication/json
{{habits.header.x-custom-header}}Custom headersAny custom value

Note: Header names are case-insensitive. {{habits.header.Authorization}} and {{habits.header.authorization}} resolve to the same value.


Environment Variables (habits.env.*)

Access environment variables for configuration and secrets.

VariableDescription
{{habits.env.VAR_NAME}}Value of environment variable
{{habits.env.OPENAI_API_KEY}}Example: OpenAI API key
{{habits.env.DATABASE_URL}}Example: Database connection string

Security Note: Use environment variables for sensitive data like API keys, passwords, and connection strings. Never hardcode secrets in workflows.

Example .env file:

env
OPENAI_API_KEY=sk-...
DATABASE_URL=postgresql://user:pass@localhost/db
API_BASE_URL=https://api.example.com

Usage in workflow:

yaml
nodes:
  - id: call-api
    data:
      params:
        apiKey: "{{habits.env.OPENAI_API_KEY}}"
        url: "{{habits.env.API_BASE_URL}}/chat"

Workflow Context (habits.context.*)

Access metadata about the current workflow execution.

VariableDescriptionExample Value
{{habits.context.workflowId}}Current workflow ID"my-workflow"
{{habits.context.workflowName}}Workflow display name"My Workflow"
{{habits.context.executionId}}Unique execution run ID"550e8400-e29b..."
{{habits.context.timestamp}}Execution start time (ISO)"2024-01-15T10:30:00.000Z"
{{habits.context.startTime}}Same as timestamp"2024-01-15T10:30:00.000Z"
{{habits.context.nodeId}}Currently executing node ID"send-email"

Use Cases:

  • Logging and auditing
  • Creating unique identifiers
  • Tracking execution flow
  • Debugging

Utility Functions (habits.function.*)

Built-in functions for common operations.

FunctionDescriptionExample Output
{{habits.function.date()}}Current date/time (ISO format)"2024-01-15T10:30:00.000Z"
{{habits.function.now()}}Alias for date()"2024-01-15T10:30:00.000Z"
{{habits.function.timestamp()}}Unix timestamp (milliseconds)1705315800000
{{habits.function.uuid()}}Generate random UUID v4"550e8400-e29b-41d4..."
{{habits.function.random(min, max)}}Random float in range0.7234 (for 0-1)
{{habits.function.randomInt(min, max)}}Random integer in range42 (for 1-100)
{{habits.function.stringify(value)}}Convert to JSON string"value"

Examples:

yaml
params:
  uniqueId: "{{habits.function.uuid()}}"
  createdAt: "{{habits.function.date()}}"
  randomScore: "{{habits.function.random(0, 100)}}"
  diceRoll: "{{habits.function.randomInt(1, 6)}}"

Previous Node Outputs ({{nodeId.*}})

Reference output from previous nodes using their node ID.

VariableDescription
{{node-id.output}}Full output from node
{{node-id.output.fieldName}}Specific field from output
{{node-id.status}}Node execution status
{{node-id.output[0]}}Array indexing

Example workflow:

yaml
nodes:
  - id: fetch-data
    data:
      module: "@ha-bits/bit-http"
      params:
        url: "https://api.example.com/users"
        method: GET

  - id: process-data
    data:
      module: "@ha-bits/bit-code"
      params:
        input: "{{fetch-data.output}}"
        # Access nested data
        firstUser: "{{fetch-data.output.data[0].name}}"

Note: Node IDs must be unique within a workflow. Use descriptive IDs like fetch-users, send-email, transform-data.


Variable Resolution Order

When a variable is evaluated, Habits checks in this order:

  1. habits.env.* - Environment variables (from process.env)
  2. habits.function.* - Utility functions
  3. habits.context.* - Workflow execution context
  4. habits.header.* - HTTP request headers
  5. habits.input.* - Request body / CLI input
  6. {nodeId}.* - Previous node outputs
  7. Direct context access - Raw context property

Examples

Complete Workflow Example

yaml
name: User Notification Workflow
nodes:
  - id: get-user
    data:
      framework: bits
      module: "@ha-bits/bit-http"
      params:
        url: "{{habits.env.API_URL}}/users/{{habits.input.userId}}"
        headers:
          Authorization: "Bearer {{habits.env.API_TOKEN}}"

  - id: send-notification
    data:
      framework: bits
      module: "@ha-bits/bit-email"
      params:
        to: "{{get-user.output.email}}"
        subject: "Hello {{get-user.output.name}}!"
        body: |
          Hi {{get-user.output.name}},
          
          This notification was sent at {{habits.function.date()}}.
          Execution ID: {{habits.context.executionId}}
          
          Best regards,
          Automated System

edges:
  - source: get-user
    target: send-notification

Using Variables in Conditions

yaml
- id: check-status
  data:
    framework: bits
    module: "@ha-bits/bit-if"
    params:
      branches:
        - value1: "{{previous-node.output.status}}"
          operator: equals
          value2: "success"
          label: on-success
        - value1: "{{previous-node.output.status}}"
          operator: equals
          value2: "error"
          label: on-error

Troubleshooting

Variable Not Resolving

Symptom: Variable appears as literal text {{habits.input.userId}}

Causes:

  1. Typo in variable path
  2. Property doesn't exist in context
  3. Node hasn't executed yet

Solution: Check the execution logs for warnings about missing properties.

Environment Variable Not Found

Symptom: Empty string returned for {{habits.env.VAR_NAME}}

Causes:

  1. Variable not set in environment
  2. Variable name case mismatch (environment variables are case-sensitive)

Solution:

  • Check .env file exists and is loaded
  • Verify exact variable name
  • Use habits.env.VAR_NAME (not $VAR_NAME)

Node Output Not Available

Symptom: Error accessing {{node-id.output}}

Causes:

  1. Node hasn't executed yet (check edge connections)
  2. Node ID typo
  3. Node was skipped due to flow control

Solution:

  • Verify edge connections in workflow
  • Check node execution status in logs
  • Use exact node ID (case-sensitive)

Released under the Apache 2.0 License.