For AI agents: the complete documentation index is available at /hclapi/llms.txt, the full documentation bundle is available at /hclapi/llms-full.txt, and this page is available as Markdown at /hclapi/docs/steps/starlark.md.

starlark

Executes sandboxed Starlark for data transformation, filtering, and business logic.

Declaration

starlark "<name>" {
  source = <<-STARLARK
    def execute(ctx):
      return { "status": "processed" }
  STARLARK
}

The script must define execute(ctx), returning a dict, list, or scalar. ctx mirrors the execution context, using dictionary access instead of dotted attributes.

Attributes

AttributeTypeRequiredDescription
labelstringyesStep identifier
sourcestringyesStarlark source defining execute(ctx)

Example: defaults and lookups

def execute(ctx):
  prefix = ctx.request.body.get("prefix", "default_prefix")
  tags = ctx.request.body.get("tags", [])
  user_id = ctx.request.body["user_id"]

  return {"prefix": prefix, "total_tags": len(tags), "user_id": user_id}

Example: list comprehension

def execute(ctx):
  raw_tags = ctx.request.body.get("tags", [])
  prefix = ctx.request.body.get("prefix", "tag")

  cleaned = [prefix + ":" + t.strip().lower() for t in raw_tags if len(t.strip()) > 0]
  return {"count": len(cleaned), "tags": cleaned}

Example: reshape prior step results

def execute(ctx):
  account = ctx.steps.fetch_account
  invoices = ctx.steps.fetch_invoices

  total_spent = sum([inv["amount_cents"] for inv in invoices if inv["status"] == "paid"])

  return {
    "account_id": account["id"],
    "name": account["name"].strip().title(),
    "total_spent_cents": total_spent
  }
Sandboxing

Starlark scripts have no filesystem or network access. Unbounded recursion and infinite loops are prevented by the runtime.