Mirra
Build

Creating Scripts (Portal)

A script is executable code that runs in a sandboxed environment on Mirra's infrastructure. This guide covers everything you need to create, test, and publish scripts on the Mirra Store.

By the end of this guide, you will understand how to write scripts in Node.js or Python, configure execution limits, test your code, implement error handling, and publish your script to the marketplace.

What is a script?

A script is custom code that runs on the Mirra platform to automate tasks, process data, and integrate services. Scripts execute in a secure, isolated environment with configurable resource limits.

How scripts work

When you create a script, you define:

  1. Execute function - The main function that processes input parameters
  2. Runtime - Node.js 18 (JavaScript/TypeScript) or Python 3.11
  3. Execution limits - Timeout, memory, and cost constraints
  4. Input parameters - The data your script accepts
  5. Return value - The results your script produces

Users execute your script through their agents by providing parameters. The platform runs your code, captures the output, and returns the results.

What scripts can do

Scripts are ideal for:

  • Data processing - Transform, analyze, or enrich data between formats
  • Task automation - Schedule and execute workflows automatically
  • Service integration - Connect multiple APIs into a single operation
  • Custom logic - Implement business-specific functionality not available in existing services

Prerequisites

Before creating a script, ensure you have:

  • Code to automate - A clear understanding of what your script should do
  • Runtime knowledge - Familiarity with JavaScript/TypeScript (Node.js) or Python
  • Test data - Sample inputs for testing your script
  • Error handling plan - How your script should handle invalid inputs or failures

Scripts run in a sandboxed environment with limited access to external resources. You cannot access the file system, make arbitrary network requests, or use certain system calls.

Supported runtimes

The developer portal supports two runtime environments for scripts.

Node.js 18 (JavaScript/TypeScript)

Node.js 18 provides a modern JavaScript runtime with full ES2022 support.

Features:

  • Modern JavaScript features (async/await, destructuring, optional chaining)
  • TypeScript support with automatic transpilation
  • NPM packages available (limited to approved packages)
  • Fast execution with V8 engine
  • JSON processing and manipulation

Best for:

  • Web API integration and data transformation
  • JSON processing and manipulation
  • Modern workflows with async operations
  • Developers familiar with JavaScript/TypeScript

Available packages: lodash, axios, date-fns, uuid, crypto-js

Contact support to request additional packages for your scripts.

Creating a script

Follow these steps to create and publish a script on the Mirra Store.

  1. Open the Developer Dashboard
  2. Click "Scripts" in the sidebar navigation
  3. Click the "Create Script" button
  4. Alternatively, use the keyboard shortcut Ctrl+Shift+N

The script editor opens with the Monaco code editor and configuration fields.

Fill in basic information

Provide essential metadata about your script:

{
  "name": "Text Analyzer",
  "description": "Analyzes text and provides detailed statistics including word count, sentence count, character count, and readability metrics",
  "runtime": "nodejs18"
}

Field requirements:

  • Name - Unique, descriptive name (3-50 characters)
  • Description - Clear explanation of what your script does (10-500 characters)
  • Runtime - Choose nodejs18 (JavaScript/TypeScript) or python3.11 (Python)

Choose a runtime based on your familiarity and the task requirements. Node.js is better for JSON processing and web APIs, while Python excels at data processing and scientific computing.

Write your code

Use the Monaco code editor with full IDE features including syntax highlighting, autocomplete, error detection, and inline documentation.

Node.js example

/**
 * Text analysis script
 * @param {Object} params - Input parameters
 * @param {string} params.text - Text to analyze
 * @returns {Object} Analysis results
 */
async function execute(params) {
  // Validate input
  if (!params.text) {
    throw new Error('text parameter is required');
  }
 
  const text = params.text;
  
  // Analyze text
  const words = text.split(/\s+/).filter(w => w.length > 0);
  const sentences = text.split(/[.!?]+/).filter(s => s.trim());
  const characters = text.length;
 
  // Calculate statistics
  const avgWordLength = words.reduce((sum, w) => sum + w.length, 0) / words.length;
  const avgSentenceLength = words.length / sentences.length;
 
  // Return results
  return {
    summary: {
      wordCount: words.length,
      sentenceCount: sentences.length,
      characterCount: characters,
      averageWordLength: Math.round(avgWordLength * 100) / 100,
      averageSentenceLength: Math.round(avgSentenceLength * 100) / 100
    },
    timestamp: new Date().toISOString()
  };
}
 
module.exports = { execute };

Python example

"""
Text analysis script
"""
from typing import Dict, Any
from datetime import datetime
 
def execute(params: Dict[str, Any]) -> Dict[str, Any]:
    """
    Analyze text and return statistics
    
    Args:
        params: Input parameters with 'text' field
        
    Returns:
        Analysis results with statistics
    """
    # Validate input
    if 'text' not in params:
        raise ValueError('text parameter is required')
    
    text = params['text']
    
    # Analyze text
    words = [w for w in text.split() if w]
    sentences = [s.strip() for s in text.split('.') if s.strip()]
    characters = len(text)
    
    # Calculate statistics
    avg_word_length = sum(len(w) for w in words) / len(words) if words else 0
    avg_sentence_length = len(words) / len(sentences) if sentences else 0
    
    # Return results
    return {
        'summary': {
            'wordCount': len(words),
            'sentenceCount': len(sentences),
            'characterCount': characters,
            'averageWordLength': round(avg_word_length, 2),
            'averageSentenceLength': round(avg_sentence_length, 2)
        },
        'timestamp': datetime.utcnow().isoformat()
    }

Function requirements:

  • Function name - Must be named execute (required)
  • Parameters - Accepts a single params object with user-provided data
  • Return value - Must return a JSON-serializable object (dict, list, string, number, boolean, or null)
  • Error handling - Throw exceptions for invalid inputs or execution failures

The platform calls your execute function with user parameters and returns the result to the agent.

Configure execution limits

Set resource limits to control costs and prevent abuse:

{
  "config": {
    "timeout": 30,
    "memory": 256,
    "maxCostPerExecution": 0.10,
    "maxExecutionsPerDay": 1000,
    "allowedResources": ["weather-api", "database-connector"]
  }
}

Configuration options:

  • Timeout - Maximum execution time in seconds (range: 1-300, default: 30)
  • Memory - RAM limit in megabytes (range: 128-2048, default: 256)
  • Max cost per execution - Maximum cost per single execution (default: $0.10)
  • Max executions per day - Daily execution limit to prevent abuse (default: 1000)
  • Allowed resources - List of resource IDs this script can access (optional)

These limits protect both you and your users from unexpected costs and resource usage. Set conservative limits initially and increase them based on actual usage patterns.

Configure trigger and setup

Define how your script can be triggered and what inputs users need to configure when creating automations.

Trigger Configuration

Specify which trigger types your script supports:

{
  "triggerConfig": {
    "types": ["event"],
    "eventTypes": ["email.received"],
    "sources": ["gmail"]
  }
}

Trigger types:

  • event - Triggered by system events (messages, emails, calendar events)
  • schedule - Triggered on a schedule (cron expression)
  • manual - Triggered by user button press or action
  • api - Triggered by API calls

For event-triggered scripts:

  • eventTypes - Array of event types this script handles (see Event Catalog)
  • sources - Array of event sources (e.g., telegram, google-gmail, google-calendar)

Available Event Types:

  • telegram.message, telegram.command
  • gmail.email_received
  • calendar.event_created, calendar.event_updated, calendar.event_deleted
  • call.started, call.ended, transcript.chunk

For schedule-triggered scripts:

  • defaultSchedule - Default cron expression (e.g., "0 9 * * *" for 9 AM daily)

Script Variables

Define variables that users configure when setting up automations. These variables are passed to your script at runtime via the event parameter.

How it works:

  1. You define variables (name, type, description)
  2. Users configure values when creating automations
  3. Your script accesses values via event.variableName

Example variable definition:

{
  "scriptVariables": [
    {
      "name": "targetChatId",
      "displayName": "Target Telegram Chat",
      "type": "resource_selector",
      "resourceType": "telegram_chat",
      "resourceMethod": "getChats",
      "required": true,
      "description": "Which Telegram chat should receive notifications?",
      "placeholder": "Select a chat...",
      "helpText": "You can choose any chat, group, or channel"
    }
  ]
}

Accessing in your script:

export async function handler(event, scriptContext, mirra) {
  // Access the user-configured variable from event.data
  const chatId = event.data.targetChatId;
  
  // Access standardized event fields
  const emailText = event.event.content.text;  // Works for any event type
  const sender = event.event.actor.name;
  
  // Use configured variable in your logic
  await mirra.resources.call({
    resourceId: 'telegram',
    method: 'sendMessage',
    parameters: {
      chatId: chatId,  // User-configured value
      text: `Email from ${sender}: ${emailText}`
    }
  });
}

Variable types:

  • text - Text input field
  • number - Numeric input
  • boolean - Checkbox/toggle
  • select - Dropdown with predefined options
  • resource_selector - Dynamic dropdown that fetches resources (chats, channels, labels)

Resource types for resource_selector:

  • telegram_chat - Telegram chats/channels
  • telegram_user - Telegram users
  • gmail_label - Gmail labels
  • slack_channel - Slack channels

Variable fields:

  • name - Variable name accessible as event.variableName in your script
  • displayName - Human-readable label shown to users
  • type - Variable type (see above)
  • required - Whether this field must be filled
  • description - Help text explaining what this variable does
  • placeholder - Placeholder text for the input
  • helpText - Additional context or tips
  • default - Default value if user doesn't provide one

UI Configuration

Configure how your script appears in different interfaces, especially the mobile app:

{
  "uiConfig": {
    "quickSetupAvailable": true,
    "category": "notification",
    "icon": "📧",
    "flowDescription": "Forwards emails to Telegram in real-time",
    "exampleUseCase": "Get instant notifications when important emails arrive"
  }
}

Configuration options:

  • quickSetupAvailable - Enable simplified mobile setup flow (auto-configures triggers)
  • category - Script category: notification, data_sync, automation, utility, reporting
  • icon - Emoji or icon identifier displayed in lists
  • flowDescription - Short description of what the script does
  • exampleUseCase - Example use case to help users understand the value

Complete Example: Email to Telegram Script

Here's a complete script configuration for an email-to-Telegram notification script:

{
  "name": "Email to Telegram Notifications",
  "description": "Forward incoming emails to a Telegram chat",
  "runtime": "nodejs18",
  "config": {
    "allowedResources": ["gmail", "telegram"],
    "timeout": 30,
    "memory": 128
  },
  "triggerConfig": {
    "types": ["event"],
    "eventTypes": ["email.received"],
    "sources": ["gmail"]
  },
  "scriptVariables": [
    {
      "name": "targetChatId",
      "displayName": "Target Telegram Chat",
      "type": "resource_selector",
      "resourceType": "telegram_chat",
      "resourceMethod": "getChats",
      "required": true,
      "description": "Which Telegram chat should receive email notifications?"
    },
    {
      "name": "includeAttachments",
      "displayName": "Include Attachments",
      "type": "boolean",
      "required": false,
      "default": false,
      "description": "Send email attachments to Telegram",
      "helpText": "Large attachments may fail due to Telegram limits"
    }
  ],
  "uiConfig": {
    "quickSetupAvailable": true,
    "category": "notification",
    "icon": "📧",
    "flowDescription": "Forwards emails to Telegram in real-time"
  }
}

With this configuration:

  • Users creating automations will only see scripts compatible with their selected trigger type
  • The mobile app will automatically configure the email.received event trigger
  • Users only need to select which Telegram chat to use
  • The setup process is simplified from 6 steps to just 2-3 steps

Test your script

Use the built-in testing tools to verify your script works correctly:

  1. Click the "Test" button in the editor toolbar
  2. Provide test parameters in JSON format:
{
  "text": "Hello world! This is a test. Testing is important."
}
  1. Click "Run Test" to execute your script
  2. View the execution results:
{
  "summary": {
    "wordCount": 8,
    "sentenceCount": 3,
    "characterCount": 51,
    "averageWordLength": 5.13,
    "averageSentenceLength": 2.67
  },
  "timestamp": "2025-11-15T12:00:00.000Z"
}
  1. Check execution logs for console output and errors
  2. Verify execution time and memory usage
  3. Test with edge cases (empty input, very long input, special characters)
  4. Test error handling with invalid inputs

Test thoroughly before publishing. Verify your script handles all expected inputs, edge cases, and error conditions correctly.

Testing checklist:

  • ✅ Valid inputs produce correct results
  • ✅ Invalid inputs throw descriptive errors
  • ✅ Edge cases are handled properly
  • ✅ Execution completes within timeout limit
  • ✅ Memory usage stays within limit
  • ✅ Error messages are helpful and clear

Publish your script

When your script is ready, publish it to make it available to users:

  1. Review all configuration and code
  2. Ensure all tests pass successfully
  3. Verify execution limits are appropriate
  4. Click "Publish" to make your script live
  5. Your script appears in the marketplace immediately

Post-publishing checklist:

  • ✅ Script appears in marketplace search
  • ✅ Users can view documentation and examples
  • ✅ Users can execute the script through their agents
  • ✅ Executions are tracked and billed correctly
  • ✅ Error handling works as expected

Your script is now live in the marketplace! Users can execute it through their agents.

Script structure

Understanding the required structure for scripts helps you write code that works correctly with the platform.

Required function signature

Every script must export an execute function with a specific signature:

async function execute(params) {
  // Your code here
  return result;
}
 
module.exports = { execute };

Requirements:

  • Function name must be execute
  • Can be async or synchronous
  • Accepts single params parameter
  • Must be exported via module.exports

Input parameters

The params object contains user-provided input data. Always validate parameters before processing to ensure your script handles invalid inputs gracefully.

Example input:

{
  "text": "Sample input text",
  "options": {
    "detailed": true,
    "format": "json"
  }
}

Validation pattern:

// Check required parameters
if (!params.text) {
  throw new Error('text parameter is required');
}
 
// Validate parameter types
if (typeof params.text !== 'string') {
  throw new Error('text parameter must be a string');
}
 
// Provide defaults for optional parameters
const options = params.options || {};
const detailed = options.detailed !== false; // default: true

Return values

Return a JSON-serializable object containing your results. The platform converts your return value to JSON and sends it to the user's agent.

Valid return types:

  • Objects (dictionaries)
  • Arrays (lists)
  • Strings
  • Numbers
  • Booleans
  • null

Example return value:

{
  "status": "success",
  "data": {
    "wordCount": 42,
    "sentenceCount": 3
  },
  "metadata": {
    "executionTime": 123,
    "timestamp": "2025-11-15T12:00:00Z"
  }
}

Invalid return types:

  • Functions
  • Undefined
  • Circular references
  • Binary data (use base64 encoding instead)

Error handling

Throw descriptive errors for invalid inputs or execution failures. The platform catches exceptions and returns error messages to users.

// Validate required parameters
if (!params.required) {
  throw new Error('required parameter is missing');
}
 
// Handle risky operations
try {
  const result = riskyOperation(params.data);
  return result;
} catch (error) {
  throw new Error(`Operation failed: ${error.message}`);
}

Best practices:

  • Use descriptive error messages
  • Include parameter names in validation errors
  • Catch and re-throw with context
  • Don't expose sensitive information in errors

Version control

The developer portal includes version control for scripts, allowing you to track changes and roll back if needed.

Creating a new version

Save a new version of your script when you make significant changes:

  1. Edit your script code in the editor
  2. Click "Save New Version" in the toolbar
  3. Enter a descriptive commit message:
Fix: Handle empty text input correctly
Add: Character frequency analysis feature
Update: Improve performance by 30%
  1. The new version is created and saved

Commit message best practices:

  • Start with a prefix: Fix:, Add:, Update:, Remove:
  • Be specific about what changed
  • Keep messages under 72 characters
  • Reference issue numbers if applicable

Viewing version history

View all versions of your script and their changes:

  1. Click the "Versions" tab in the editor

  2. View the version list with:

    • Version number - Sequential version identifier (v1, v2, v3, etc.)
    • Commit message - Description of changes
    • Timestamp - When the version was created
    • Author - Who created the version
  3. Click on a version to view its code

Rolling back to a previous version

Restore a previous version if you need to undo changes:

  1. Select the previous version from the version list
  2. Click "Restore This Version"
  3. Confirm the action in the dialog
  4. The selected version becomes the current version

Published scripts always use the latest version. When you restore a previous version, it becomes the new latest version and users will execute that code.

Version control tips:

  • Create versions before major changes
  • Test thoroughly before creating a new version
  • Use descriptive commit messages
  • Keep a changelog of significant changes

Testing strategies

Comprehensive testing ensures your script works correctly for all inputs and edge cases.

Unit testing

Test individual functions and logic in isolation:

// Test helper function
function testWordCount() {
  const result = countWords("hello world");
  if (result !== 2) {
    throw new Error(`Expected 2, got ${result}`);
  }
  console.log("✓ Word count test passed");
}
 
// Run tests
testWordCount();

Unit testing best practices:

  • Test each function independently
  • Use descriptive test names
  • Test both success and failure cases
  • Verify edge cases and boundary conditions

Integration testing

Test with real data to verify end-to-end functionality:

const testData = {
  text: "Real sample text from production with multiple sentences. This tests actual usage."
};
 
const result = await execute(testData);
console.log("Integration test result:", result);
 
// Verify result structure
if (!result.summary || !result.summary.wordCount) {
  throw new Error("Invalid result structure");
}

Integration testing best practices:

  • Use realistic test data
  • Test the complete execute function
  • Verify result structure and types
  • Test with data from actual use cases

Edge case testing

Test boundary conditions and unusual inputs:

// Empty input
try {
  execute({ text: "" });
  console.log("✓ Empty input handled");
} catch (error) {
  console.log("✗ Empty input failed:", error.message);
}
 
// Very long input (stress test)
execute({ text: "word ".repeat(10000) });
 
// Special characters
execute({ text: "!@#$%^&*()" });
 
// Unicode and emojis
execute({ text: "Hello 世界 🌍" });
 
// Missing parameters
try {
  execute({});
  console.log("✗ Should have thrown error for missing params");
} catch (error) {
  console.log("✓ Missing params handled correctly");
}

Edge case testing checklist:

  • ✅ Empty strings and arrays
  • ✅ Very long inputs (stress testing)
  • ✅ Special characters and punctuation
  • ✅ Unicode and emoji characters
  • ✅ Missing required parameters
  • ✅ Invalid parameter types
  • ✅ Null and undefined values
  • ✅ Extreme numbers (very large, very small, negative)

Publishing your script

Publishing makes your script available to all users in the marketplace.

Pre-publishing checklist

Before publishing, ensure your script meets these requirements:

  • ✅ All tests pass successfully
  • ✅ Error handling covers all edge cases
  • ✅ Execution limits are appropriate
  • ✅ Code is well-documented with comments
  • ✅ Description clearly explains functionality
  • ✅ Examples demonstrate common use cases

Publishing process

  1. Review all configuration and code one final time
  2. Test with multiple input scenarios
  3. Verify execution time and memory usage
  4. Click "Publish" in the editor toolbar
  5. Confirm publishing in the dialog
  6. Your script goes live immediately

After publishing

Once published, your script is immediately available to users:

  • ✅ Script appears in marketplace search results
  • ✅ Users can view documentation and examples
  • ✅ Users can execute your script through their agents
  • ✅ Execution tracking begins automatically
  • ✅ Users can submit reviews and ratings
  • ✅ Revenue tracking starts (for paid scripts)

Monitor your script's performance and user feedback to identify improvements.

Best practices

Follow these best practices to create high-quality, reliable scripts.

Code quality

Write clean, maintainable code that is easy to understand and modify:

  • Use descriptive names - Choose clear variable and function names that explain their purpose
  • Add comments - Explain complex logic and non-obvious decisions
  • Follow conventions - Use language-specific style guides (ESLint for JavaScript, PEP 8 for Python)
  • Keep functions focused - Each function should do one thing well
  • Avoid duplication - Extract repeated code into reusable functions

Example:

// Good: Descriptive names and clear logic
function calculateAverageWordLength(words) {
  const totalLength = words.reduce((sum, word) => sum + word.length, 0);
  return words.length > 0 ? totalLength / words.length : 0;
}
 
// Bad: Unclear names and purpose
function calc(w) {
  const t = w.reduce((s, x) => s + x.length, 0);
  return w.length > 0 ? t / w.length : 0;
}

Performance optimization

Optimize your code to reduce execution time and memory usage:

  • Choose efficient algorithms - Use appropriate data structures and algorithms for your task
  • Avoid unnecessary loops - Combine operations when possible
  • Cache repeated calculations - Store results of expensive operations
  • Process data in batches - Handle large datasets incrementally
  • Monitor resource usage - Track execution time and memory consumption

Example:

// Good: Cache expensive calculations
const cache = new Map();
function expensiveOperation(input) {
  if (cache.has(input)) {
    return cache.get(input);
  }
  const result = /* expensive calculation */;
  cache.set(input, result);
  return result;
}
 
// Bad: Recalculate every time
function expensiveOperation(input) {
  return /* expensive calculation */;
}

Security considerations

Protect your script and users from security vulnerabilities:

  • Validate all inputs - Check types, ranges, and formats before processing
  • Sanitize user data - Remove or escape potentially dangerous content
  • Avoid eval() or exec() - Never execute user-provided code
  • Don't log sensitive data - Avoid logging passwords, API keys, or personal information
  • Use approved packages - Only use packages approved by the platform

Example:

// Good: Validate and sanitize input
function processUserInput(input) {
  if (typeof input !== 'string') {
    throw new Error('Input must be a string');
  }
  const sanitized = input.replace(/[<>]/g, ''); // Remove dangerous characters
  return sanitized;
}
 
// Bad: No validation or sanitization
function processUserInput(input) {
  return input; // Potentially dangerous
}

Error handling best practices

Implement robust error handling to improve user experience:

  • Catch all exceptions - Handle both expected and unexpected errors
  • Provide helpful messages - Explain what went wrong and how to fix it
  • Log errors for debugging - Include context and stack traces in logs
  • Don't expose internals - Avoid revealing implementation details in error messages
  • Return consistent formats - Use a standard error response structure

Example:

// Good: Descriptive error with context
if (!params.email || !params.email.includes('@')) {
  throw new Error('Invalid email address. Please provide a valid email in the format: user@example.com');
}
 
// Bad: Vague error message
if (!params.email || !params.email.includes('@')) {
  throw new Error('Invalid input');
}

Documentation practices

Document your script to help users understand how to use it:

  • Document parameters - Explain what each parameter does and its expected format
  • Explain return values - Describe the structure and meaning of return data
  • Provide usage examples - Show common use cases with sample inputs and outputs
  • List dependencies - Note any required resources or external services
  • Include troubleshooting tips - Help users resolve common issues

Troubleshooting

Common issues when creating scripts and their solutions.

Timeout errors

Problem: Your script exceeds the execution time limit.

Solutions:

  • Optimize your code - Reduce algorithmic complexity and eliminate unnecessary operations
  • Process data incrementally - Handle large datasets in smaller chunks
  • Cache expensive operations - Store and reuse results of repeated calculations
  • Request higher limits - Contact support to increase timeout limits for your account
  • Split into smaller scripts - Break complex operations into multiple scripts

Example optimization:

// Bad: O(n²) complexity
for (let i = 0; i < items.length; i++) {
  for (let j = 0; j < items.length; j++) {
    // comparison
  }
}
 
// Good: O(n) complexity with Set
const itemSet = new Set(items);
for (const item of items) {
  if (itemSet.has(item)) {
    // comparison
  }
}

Memory errors

Problem: Your script runs out of memory.

Solutions:

  • Process data in chunks - Handle large datasets incrementally instead of loading everything at once
  • Release unused variables - Set large variables to null when no longer needed
  • Use efficient data structures - Choose appropriate data structures for your use case
  • Stream data - Process data as it arrives instead of buffering everything
  • Request more memory - Contact support to increase memory limits

Example:

// Bad: Load everything into memory
const allData = await fetchLargeDataset();
const results = allData.map(process);
 
// Good: Process in chunks
const chunkSize = 1000;
const results = [];
for (let i = 0; i < totalItems; i += chunkSize) {
  const chunk = await fetchChunk(i, chunkSize);
  results.push(...chunk.map(process));
}

Import errors

Problem: Cannot import required packages.

Solutions:

  • Use approved packages only - Check the list of available packages for your runtime
  • Verify package names - Ensure you're using the correct package name and import syntax
  • Contact support - Request new packages to be added to the approved list
  • Use built-in modules - Prefer standard library modules when possible

Available packages:

  • Node.js: lodash, axios, date-fns, uuid, crypto-js
  • Python: requests, pandas, numpy, dateutil, pydantic

Execution errors

Problem: Script fails during execution with unexpected errors.

Solutions:

  • Add comprehensive error handling - Catch and handle all possible exceptions
  • Validate inputs thoroughly - Check all parameters before processing
  • Test with edge cases - Verify your script handles unusual inputs correctly
  • Check execution logs - Review logs for detailed error messages and stack traces
  • Add defensive programming - Check for null/undefined values before accessing properties

Next steps

Now that you understand how to create scripts, explore these related topics:

See also

On this page