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

# Function syntax

> Reference guide for the Stratus function scripting syntax and available APIs.

<head>
  <script type="application/ld+json">
    {JSON.stringify({
            "@context": "https://schema.org",
            "@graph": [
              {
                "@type": "TechArticle",
                "headline": "Function syntax",
                "description": "Reference guide for the Stratus function scripting syntax and available APIs.",
                "author": {"@type": "Organization", "name": "Snag Solutions", "url": "https://www.snagsolutions.io/"},
                "publisher": {"@type": "Organization", "name": "Snag Solutions", "url": "https://www.snagsolutions.io/", "logo": {"@type": "ImageObject", "url": "https://assets.snagsolutions.io/public/docs/snag-logo-dark-no-bg.svg"}},
                "mainEntityOfPage": "https://docs.snagsolutions.io/stratus/syntax"
              },
              {
                "@type": "BreadcrumbList",
                "itemListElement": [
                  {"@type": "ListItem", "position": 1, "name": "Home", "item": "https://docs.snagsolutions.io/welcome"},
                  {"@type": "ListItem", "position": 2, "name": "Stratus", "item": "https://docs.snagsolutions.io/stratus/stratus-overview"},
                  {"@type": "ListItem", "position": 3, "name": "Functions", "item": "https://docs.snagsolutions.io/stratus/functions"},
                  {"@type": "ListItem", "position": 4, "name": "Syntax"}
                ]
              }
            ]
          })}
  </script>
</head>

<Tip>
  **Using an AI coding assistant?** Connect Cursor, Claude, or Copilot to Snag Docs for context-aware help. [Learn how](/ai-coding-assistant).
</Tip>

## Overview

To maintain consistency and security, all Stratus functions are validated before they are saved. This guide explains the required syntax, module restrictions, and best practices to help you create functions that pass validation.

## Module Export & Handler Function

### Single Handler Export

Your code must export exactly one handler function.

<Warning>
  Exporting multiple handler definitions or not exporting a handler at all will cause validation to fail.
</Warning>

```javascript theme={null}
// ❌ Incorrect – no exported handler:
const handler = async (input, output) => { ... };
```

### Proper Export Format

Always export your handler as a property of `module.exports`.

```javascript theme={null}
// ✅ Correct:
module.exports.handler = async (input, output) => {
  // Function body...
}
```

<Note>
  The exported handler must be a function. Assigning non-function values (e.g., a string) will trigger an error.
</Note>

## Handler Function Parameters & Behavior

### Parameter Requirements

The handler function must accept exactly two parameters:

* `input` – holds input data
* `output` – provides methods for setting and building the function's output

```javascript theme={null}
module.exports.handler = async (input, output) => { ... };
```

### Using output.setResult

Inside your handler, you must call `output.setResult` to set the result object.

```javascript theme={null}
// ❌ Incorrect:
module.exports.handler = async (input, output) => {
  // Missing call to output.setResult
  return output.buildOutput()
}
```

### Calling output.buildOutput()

<Warning>
  The handler must return the result of `output.buildOutput()`. Omitting this call is not allowed.
</Warning>

```javascript theme={null}
// ✅ Correct:
module.exports.handler = async (input, output) => {
  output.setResult({ message: 'Hello' })
  return output.buildOutput()
}
```

<Note>
  If the handler does not accept exactly two parameters, validation will fail with a message similar to: "The 'handler' function must accept exactly two parameters: 'input' and 'output'."
</Note>

## Module Import Requirements

### Allowed Modules

You may include external modules via `require()`, but only approved packages are allowed:

* `axios`
* `lodash`
* `viem` and its approved subpath `viem/chains`

```javascript theme={null}
const axios = require('axios')
```

### Disallowed Modules

<Warning>
  The following are not allowed:

  * Modules not on the approved list (e.g., Node's `fs`)
  * Unapproved subpaths from approved packages
  * Dynamic requires (using variables for module names)
</Warning>

```javascript theme={null}
// ❌ Incorrect:
const mod = 'axios'
const axios = require(mod) // Dynamic require not allowed
```

### Extra Exports

Adding extra properties to `module.exports` (aside from the handler) is allowed and will not affect validation:

```javascript theme={null}
module.exports.extra = 'some extra value'
module.exports.handler = async (input, output) => {
  output.setResult({ message: 'Hello' })
  return output.buildOutput()
}
```

## JavaScript Syntax

### Valid JavaScript

Your code must be syntactically valid JavaScript. Common syntax errors include:

* Missing closing braces
* Unmatched parentheses
* Invalid syntax

```javascript theme={null}
// ❌ Example of Syntax Error:
module.exports.handler = async (input, output) => {
  output.setResult({ message: "Hello" })
  return output.buildOutput(;  // Error: Unmatched parenthesis
};
```

## Common Validation Error Messages

You may encounter the following validation errors:

<CodeGroup>
  ```bash Common Errors theme={null}
  "Module 'unknown/chains' is not approved"
  "User code must export exactly one handler function"
  "Invalid dynamic require detected"
  "Failed to validate user code: ..."
  "The 'handler' property must be assigned to a function"
  "Multiple handler definitions found"
  "The 'handler' function must accept exactly two parameters: 'input' and 'output'"
  "The 'handler' function must use output.setResult"
  "The 'handler' function must call output.buildOutput()"
  ```
</CodeGroup>

## Examples

### Valid Stratus Function with External Module

```javascript theme={null}
const axios = require('axios')

module.exports.handler = async (input, output) => {
  const response = await axios.get('https://example.com')
  output.setResult({ data: response.data })
  return output.buildOutput()
}
```

### Valid Function Without External Modules

```javascript theme={null}
module.exports.handler = async (input, output) => {
  output.setResult({ message: 'Hello World!' })
  return output.buildOutput()
}
```

### Common Mistakes

<AccordionGroup>
  <Accordion title="Multiple Handler Exports">
    ```javascript theme={null}
    // ❌ Incorrect: Multiple handler definitions
    module.exports.handler = async (input, output) => { ... };
    module.exports.handler = async (input, output) => { ... };
    ```
  </Accordion>

  <Accordion title="Missing Output Calls">
    ```javascript theme={null}
    // ❌ Incorrect: Missing output.setResult
    module.exports.handler = async (input, output) => {
      return output.buildOutput();
    };
    ```
  </Accordion>

  <Accordion title="Dynamic Require Usage">
    ```javascript theme={null}
    // ❌ Incorrect: Dynamic require
    const mod = 'axios';
    const axios = require(mod);
    ```
  </Accordion>
</AccordionGroup>

## Summary

To ensure your Stratus function passes syntax validation:

* Export one handler function using the correct module export syntax
* Ensure the handler is asynchronous and accepts exactly two parameters: `input` and `output`
* Call both `output.setResult` and `output.buildOutput()` within your handler
* Import only approved modules using string literals (no dynamic requires)
* Write valid JavaScript with correct syntax
