Portal Community

Required Structure

// Minimum required structure
function execute(input) {
    // Process input
    // Return a JSON-serialisable value
    return { result: "ok" };
}

// Arrow function style also works
const execute = (input) => {
    return { result: "ok" };
};

Example: Leave Day Calculator

function execute(input) {
    const startDate  = new Date(input.startDate);
    const endDate    = new Date(input.endDate);
    const entitlement= parseInt(input.annualEntitlement) || 20;
    const usedDays   = parseInt(input.usedDays) || 0;

    // Calculate working days between dates (Mon-Fri only)
    let requestedDays = 0;
    let current = new Date(startDate);
    while (current <= endDate) {
        const day = current.getDay();
        if (day !== 0 && day !== 6) requestedDays++;  // Skip Sunday=0, Saturday=6
        current.setDate(current.getDate() + 1);
    }

    const remaining = entitlement - usedDays;
    const canApprove = requestedDays <= remaining;

    return {
        requestedDays:  requestedDays,
        remainingBefore: remaining,
        remainingAfter:  canApprove ? remaining - requestedDays : remaining,
        canApprove:      canApprove,
        message: canApprove
            ? `Leave request for ${requestedDays} days approved. ${remaining - requestedDays} days remaining.`
            : `Insufficient leave balance. Requested ${requestedDays} days but only ${remaining} remaining.`
    };
}

Example: JSON Transformer

// Transform a raw API response into a clean summary
function execute(input) {
    const items = input.items || [];

    // Filter, map, and sort
    const summary = items
        .filter(item => item.status === "active")
        .map(item => ({
            id:       item.id,
            name:     item.name,
            quantity: item.inventory?.quantity ?? 0,
            category: item.metadata?.category ?? "Uncategorized"
        }))
        .sort((a, b) => b.quantity - a.quantity)
        .slice(0, 10);  // Top 10 by quantity

    return {
        totalActive: items.filter(i => i.status === "active").length,
        topItems:    summary,
        generatedAt: new Date().toISOString()
    };
}

Error Handling Pattern

function execute(input) {
    // Validate required inputs
    if (!input.employeeId) {
        return { error: "missing_field", message: "employeeId is required" };
    }

    try {
        // Main logic
        const result = processEmployee(input.employeeId);
        return { success: true, data: result };
    } catch (err) {
        // Return structured error — don't throw (unhandled throws become runtime errors)
        return {
            error:   "execution_error",
            message: err.message || "An unexpected error occurred"
        };
    }
}

// Helper function defined at module level
function processEmployee(id) {
    // ... logic ...
    return { id: id, processed: true };
}

Common Pitfalls

PitfallProblemFix
Missing return statementFunction returns undefined — serialised as nullAlways return an explicit value
Circular references in return valueJSON serialisation failsReturn only plain objects with no circular refs
Using Date.now() for determinismNon-deterministic output makes testing difficultAccept date inputs explicitly if needed
Infinite loopsFunction hits timeout (5s) and is killedAlways use bounded loops; test edge cases
Large return objectsResult injected into LLM context — large objects waste tokensReturn only what the LLM needs