Type to search.

Debug sandbox limitations in Painless

Serverless

Elastic Cloud Serverless projects are autoscaled environments, fully managed by Elastic and available on Elastic Cloud.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Serverless interfaces and procedures might differ from classic Elastic Stack deployments.

Stack

The Elastic Stack includes Elastic's core products such as Elasticsearch, Kibana, Logstash, and Beats.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Unless stated otherwise on the page, this functionality is available when your Elastic Stack is deployed on Elastic Cloud Hosted, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and self-managed environments.

This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes.

Painless implements sandbox limitations that differ from standard Java syntax and behavior. These restrictions are designed to optimize performance and prevent logical errors, which can lead to unexpected compilation errors when common Java patterns are used. One limitation is that empty foreach loops are not allowed.

Follow these guidelines to avoid Painless sandbox restriction errors in your script:

  • Empty loops: Painless intentionally prohibits empty foreach loops for performance reasons.
  • Syntax differences: Painless syntax differs from Java in several ways to optimize execution and prevent logical errors.

For details, refer to the following sample error and solution.

JSON
{
  "error": {
    "root_cause": [
      {
        "type": "script_exception",
        "reason": "compile error",
        "script_stack": [
          """... keyboard": 85];

        for (item in products.ent ...""",
          "                             ^---- HERE"
        ],
        "script": """
        Map products = ["laptop": 1200, "mouse": 25, "keyboard": 85];

        for (item in products.entrySet())
        {


        }

        return false;
    """,
        "lang": "painless",
        "position": {
          "offset": 80,
          "start": 55,
          "end": 105
        }
      }
    ],
    "type": "script_exception",
    "reason": "compile error",
    "script_stack": [
      """... keyboard": 85];

        for (item in products.ent ...""",
      "                             ^---- HERE"
    ],
    "script": """
        Map products = ["laptop": 1200, "mouse": 25, "keyboard": 85];

        for (item in products.entrySet())
        {


        }

        return false;
    """,
    "lang": "painless",
    "position": {
      "offset": 80,
      "start": 55,
      "end": 105
    },
    "caused_by": {
      "type": "illegal_argument_exception",
      "reason": "extraneous foreach loop"
    }
  },
  "status": 400
}
JSON
{
    "script": {
      "lang": "painless",
      "source": """
        Map products = ["laptop": 1200, "mouse": 25, "keyboard": 85];

       for (item in products.entrySet())
       {


        }

        return false;
      """
    }
}
  • Empty loop blocks: Painless does not allow empty foreach loops as an intentional feature to enhance usability and performance.
  • Performance optimization: Since scripts run once per document and there may be millions of documents, empty loops are considered wasteful.

The error occurs because Painless expects meaningful code inside loop blocks and treats empty loops as potential bugs or risks.

Always include actual code inside foreach loops. For example:

JSON
POST _scripts/painless/_execute
{
  "script": {
    "lang": "painless",
    "source": """
      Map products = ["laptop": 1200, "mouse": 25, "keyboard": 85];
      String inventory = "";

      for (item in products.entrySet())
      {
        inventory += item.getKey() + " costs $" + item.getValue() + ". ";
      }

      return inventory;
    """
  }
}