The node inspector

The flow editor's right-hand panel: a node's YAML, the variables it reads, request params, headers, its last response, and an AI chat scoped to it.

9 min read

Click any node on the graph and the inspector on the right fills with everything about it, organized into tabs: the node’s own YAML, the variables it reads, structured request fields, the result of the last run, and an AI chat that already knows which node you are looking at. Each tab is described below in the order it appears.

Node

The selected node’s complete YAML (type, config, and routing) in a small code editor. Anything about a node can be changed here: the URL, a header, next to rewire the flow, a field no structured panel exposes. Edits are validated as you type; a parse error shows a red banner until fixed.

The other panels are shortcuts into this same YAML, not alternatives to it. Routing can also be rewired by dragging on the graph.

The ? button in the panel header opens the in-app reference at the selected node’s type: the fields it takes and a worked example, without leaving the app or reaching for a browser. F1 opens the same reference at its table of contents: every node type plus variables and environments, data-driven runs, hooks, retry and polling, and logging. It’s bundled with the app at build time, so it works offline.

Variables

Every env.X and variables.X reference this node consumes, one row each:

  • Source badge shows where the value comes from: .env, a flow variable, captured by {node} (click it to jump to the producing node), an override, or unset.
  • Value preview: values from .env are masked by default; each row has a reveal toggle.
  • Override takes a value that applies to runs from this machine only. Overrides are stored locally, never written into the .aether file, so a temporary token or a teammate-specific value can’t leak into Git.
  • Promote is for when you decide an override belongs in the flow; one click writes it into the flow’s variables: block and clears the override.

Unset references get a badge here and on the graph. The full resolution rules are in Variables & environments.

Params (request nodes)

A form for the whole request, so a routine edit doesn’t mean hand-editing YAML. Top to bottom:

  • Endpoint holds the method (a dropdown) and the url. Placeholders are welcome: https://api.example.com/users/{id}.
  • Headers: key/value rows. Values take ${{ }} interpolation, so an auth header can read Bearer ${{ variables.token }}.
  • Path params get a row automatically for every {name} or :name placeholder in the URL; fill in each value inline. No placeholders, no rows.
  • Query params are key/value rows with an Add row at the bottom and a remove button per row. They’re stored as structured queryParams, not smuggled into the URL string.
  • Capture lists the variable names this node produces and the expressions that produce them (tokenresponse.body.token). Everything captured here is readable by later nodes; see Variables & environments.
  • Options covers the request’s timeout (ms) (empty means the default 30 seconds) and its retry policy: attempts, delay (ms), backoff, and until.
  • Streaming (SSE) is a checkbox and three fields, for reading a text/event-stream response into response.body as an array of events. Tick Read the response as a stream and you get expectEvents (stop after N), waitFor (JavaScript run after each event, with event as the one just received and events as everything so far), and a timeout (ms) that is deliberately separate from the request timeout above: that one bounds getting the response, and a stream that starts promptly then runs for minutes is the normal case. Full semantics: Server-Sent Events.

Retry is worth a sentence, because the two modes look the same and aren’t. With attempts alone, the node re-runs only when it throws (a connection reset, a timeout). Add an until expression (response.status === 200) and it becomes polling: the node re-runs until that expression is truthy, whether or not the call failed. The panel says which of the two you’ve configured underneath the fields. Full semantics: retry & poll-until.

Every value here can reference variables (${{ variables.userId }}) just like the URL itself.

Body (request nodes)

A JSON-aware editor for the request body, with syntax highlighting, live validation, and a Format JSON button that reindents a one-liner into readable JSON:

  • The status line tells you where you stand: Valid JSON, Valid JSON with ${{ }} interpolations, or the exact parse error. Non-JSON bodies (form-encoded, plain text) are fine; the panel says “Plain text body” and stays out of your way.
  • If the body is JSON but the request has no Content-Type header, a one-click chip adds Content-Type: application/json.

A body is not always a string, though, and the tab follows the shape of the one you have.

GraphQL requests

A node with a graphql block gets the GraphQL editor here, since the query is that node’s body. It holds the query (a Monaco editor with GraphQL syntax highlighting), variables as a JSON object, an operationName field, and a checkbox for letting a response carrying errors pass.

Two things the panel tells you that the YAML does not. The variables box reports the exact JSON error rather than silently keeping the last good value, and operationName is only pointed out as necessary when the document declares more than one operation. The highlighting is highlighting and nothing more: there is no GraphQL schema loaded, so nothing here checks a field name against your API.

The errors checkbox is worth reading before you tick it. GraphQL servers answer 200 even when execution failed, so by default a non-empty errors array fails the node. Ticking it means you intend to assert on response.body.errors yourself.

File uploads and binary bodies

A multipart or binary body is a structured block rather than a string, and each has its own editor here:

  • multipart/form-data lists the fields, and each one switches between a text value and a file read from disk. Choose file… opens your operating system’s file picker. A file field also takes filename, which is what the server is told the file is called and is worth setting when an upload endpoint validates it, and contentType.
  • binary picks between a filePath and an inline base64 string, plus the contentType the format requires.

The picker answers with an absolute path, which always works. A relative path resolves against the flow file’s own folder, which is what you want for a fixture checked in beside the flow, so the panel says so rather than rewriting your path for you.

Both editors hold an edit back until it validates. Adding a field, or switching one from text to file, passes through a state the format does not accept, so the panel shows what you are typing while the file keeps the last version that parsed, and says as much underneath. Everything these editors write is ordinary YAML: the panel is the convenient route to the block, not a different way of storing it.

gRPC & WebSocket (their own nodes)

grpc and websocket nodes don’t use Params/Body. Each gets a dedicated config panel in their place. The gRPC panel covers the service and method, the .proto file or server reflection, and the request message; the WebSocket panel covers the URL, subprotocols, the messages to send, and how long to collect replies. The Variables and Result sub-tabs work the same as for any other node.

Result

What this node did on the last run:

  • Request (request nodes) shows the exact method, URL, headers, and body that went out, with every variable already resolved. When a request misbehaves, this is the ground truth of what was actually sent.
  • Result: for a request, the response status, headers, and body; for a condition, which branch it took and why; for captures, scripts, and AI actions, the variables they produced and their values.

Beside the status sit two badges: how long the node took (823 ms, or 1.4 s past a second) and, for a request, how big the response was. Every node type is timed, not just requests, which is how you find the script node that’s quietly costing you four seconds.

Before the first run it shows a placeholder; run the flow to fill it.

Reading a response that isn’t JSON

Pretty re-indents more than JSON. An XML or SOAP document is reflowed with one element per line, which is the difference between reading a SOAP envelope and scrolling one. It is a formatter and not a parser, deliberately: a malformed document gets reflowed rather than rejected, because a malformed document is usually the one you are trying to look at.

A CSV or TSV body renders as a table with a sticky header, since a table is the only reading of a CSV anybody actually does. Very large exports are truncated with a note saying so, on the grounds that a 50,000-row export is a download rather than a read.

A binary body says it is binary and points at Save response below, instead of arriving as a screenful of mojibake that looks like a broken viewer.

Copy the request as code

Copy as… on the Request tab turns the resolved request into working code in six languages: cURL, JavaScript fetch, Node axios, Python requests, Go (standard library, no third-party import) and HTTPie. It is generated from the request that actually went out, variables already substituted, so what you paste is what ran. Useful for handing a reproduction to someone who does not have Bandura, or for dropping a call into application code once the flow proves it works. The same button sits on every recorded request in Execution history.

Filter the response with JSONPath

Under the response body is a JSONPath box. Type $.items[*].id and the panel shows just the matches, which beats scrolling a 400-line payload to check one field. It supports the common syntax: $ root, dot and bracket child access, array indexes including negative ones, wildcards, recursive descent (..name) and slices ([1:3]). Filter expressions and script expressions are not supported. A path that does not parse shows a quiet inline message and leaves the rest of the panel alone.

Save the response to a file

Save response writes the body to disk exactly as it came off the wire, through your operating system’s normal save dialog. The target can be anywhere you can write, not just inside the workspace, because a downloaded PDF or CSV usually does not belong next to your flows.

Chat

An AI chat that knows your flow. Ask why a node failed, how to write a check, or what a response means. Enter sends, Shift+Enter adds a newline. Requires an AI provider, either Anthropic or any OpenAI-compatible endpoint (Connect an AI provider).

The bottom panel

Below the editor (toggle with ⌘J): Console (timestamped execution log), Variables (the live snapshot from the last run), History (Execution history), and Terminal (The built-in terminal).

Last updated

Looking for something else? All 37 articles are on one page in the Help Center.