Variables & BotData

BotData is the shared state object for a single bot execution. Every variable produced by a block lives in BotData and is accessible by all subsequent blocks via <varName> syntax.

BotData Overview

Each bot run has its own BotData instance, isolated from other bots running concurrently. BotData holds:

  • All variables (automatic and user-defined)
  • The current bot status (NONE, SUCCESS, FAILURE, etc.)
  • Cookie jar and session objects for HTTP, IMAP, POP3, SMTP, FTP
  • The log for the current run

Variables in BotData persist for the entire script run and are cleared when the bot finishes.

Automatic Variables

These variables are set automatically after certain blocks execute. They are always available in Keycheck and Parse combo-boxes.

VariableSet byContent
<SOURCE> HTTP Request, TLS Request, Navigate (Selenium) Response body decoded as UTF-8 text. For Selenium, this is the page HTML.
<RESPONSECODE> HTTP Request, TLS Request HTTP status code as a string, e.g. "200", "403".
<ADDRESS> HTTP Request, TLS Request, Navigate Final URL after all redirects. For Selenium, the current page URL.
<HEADERS(*)> HTTP Request, TLS Request All response headers concatenated as a single string.
<HEADERS{name}> HTTP Request, TLS Request A specific response header by name, e.g. <HEADERS{Content-Type}>.
<COOKIES(*)> HTTP Request, TLS Request All cookies as a string.
<COOKIES{name}> HTTP Request, TLS Request A specific cookie by name.
<ERROR> Any block that throws an exception See below.
<PROXY> Runner / Debugger (when Use Proxies is on) The current proxy as host:port only (no credentials). Cosmetic — the real proxy authentication travels inside the proxy object, not this string.
<PROXYFULL> Runner / Debugger (when Use Proxies is on) The complete proxy string host:port:user:pass (or host:port when the proxy has no authentication). Use it to reuse the authenticated proxy inside the config (scripts, a second hop, a header, …).

The <ERROR> Variable

<ERROR> is a special hidden variable that is set whenever any block throws an unhandled exception during execution.

How it works

  1. A block's Process() method throws an exception.
  2. LoliScript catches the exception and writes ex.Message to BotData.ErrorMessage.
  3. BotData.ErrorMessage writes the value into the "ERROR" hidden variable.
  4. Subsequent blocks (especially Keycheck) can read <ERROR> like any other variable.

Key Difference: HTTP vs Protocol Blocks

Block TypeOn Exception
HTTP Request, Captcha, BypassCF Sets <ERROR>, sets bot status to ERROR, stops script
IMAP, POP3, SMTP, FTP, TCP Sets <ERROR>, script continues — use Keycheck to classify
💡

Always place a Keycheck immediately after IMAP / POP3 / SMTP / FTP blocks to handle both success and error cases. Check <ERROR> for strings like "Authentication failed", "Too many connections", "535", etc.

Example

IMAP Connect "imap.libero.it" "993" (UseSSL=True) 30000
IMAP Login "<email>" "<pass>"
KEYCHECK
  KEYCHAIN Failure OR
    KEY "<ERROR>" Contains "Authentication failed"
  KEYCHAIN Ban OR
    KEY "<ERROR>" Contains "Too many"
  KEYCHAIN Success OR
    KEY "<ERROR>" DoesNotExist

Single vs List Variables

Variables in BotData have one of two types:

TypeAccess syntaxSet by
Single <varName> Most blocks — HTTP response, IMAP count, Parse (first match), Function output
List <varName[0]> — first item
<varName[*]> — all items joined
Parse with "List" output, IMAP ListFolders, FTP ListFiles, Function Split

Accessing List Items

PARSE <SOURCE> CSS ".item" ATTRIBUTE:"innerText" LIST -> "items"

# Use first item
REQUEST GET "https://api.example.com/<items[0]>"

# Use all items joined by space (for logging or keycheck)
KEYCHECK
  KEYCHAIN Success OR
    KEY "<items[*]>" Contains "premium"

Capture Flag

Variables can be marked as captured. Captured variables are saved alongside the hit in the Hits DB when the bot status is SUCCESS or a capture-enabled CUSTOM status.

In the Stacker UI, enable the capture toggle on any output variable field. In LoliScript, add CAP at the end of the variable name:

PARSE <SOURCE> JSON "user.plan" -> "planType" CAP
PARSE <SOURCE> JSON "user.balance" -> "balance" CAP

Both planType and balance will appear in the Hits DB entry for this bot run.

Context-Aware Variable Suggestions

OBM2 Pro analyzes all blocks above the currently selected block in the Stacker and extracts the output variable names. These names are offered as suggestions in combo-box dropdowns throughout the block UI.

How Extraction Works

The StackVariableExtractor helper (in OpenBullet/Helpers/) inspects each block in order via reflection, extracting:

  • VariableName — Parse, Function, IMAP, FTP, POP3
  • OutputVariable — HTTP Request, TLS Request
  • VarName — Utility

Captcha blocks always contribute the fixed names: CAPTCHAID, SOLUTION, GT_CHALLENGE, GT_VALIDATE, GT_SECCODE.

ℹ

Suggestions update every time you select a block in the Stacker, not only on initial load. If you add a new Parse block above the current one, deselect and reselect the block to refresh the dropdown.

Variable Syntax Reference

SyntaxMeaning
<varName>Value of a Single variable
<varName[0]>First element of a List variable
<varName[2]>Third element (0-based index)
<varName[*]>All elements of a List joined by space
<SOURCE>Last HTTP/browser response body
<RESPONSECODE>Last HTTP status code
<ADDRESS>Last final URL
<HEADERS(*)>All response headers as string
<HEADERS{X-Auth}>Specific header value
<COOKIES(*)>All cookies as string
<COOKIES{session}>Specific cookie value
<ERROR>Last exception message (empty if no error)
<PROXY>Current proxy as host:port (no credentials)
<PROXYFULL>Current proxy as host:port:user:pass (or host:port if no auth)

Variable substitution is performed by ReplaceValues() in BlockBase before every field is used in a request or condition. This means you can embed variables in URLs, POST bodies, headers, and key values.