Open Source API Gateway

500 Internal Server Error: Error Executing Groovy Script

Membrane API Gateway returns 500 Internal Server Error with the title Error executing script. when a script in the groovy plugin throws an exception while it runs. The script is part of the gateway configuration, so the configuration is at fault, even when unexpected message content triggered the error.

The Error Response

The response contains the status 500 Internal Server Error, the title Error executing script., the problem type https://membrane-api.io/problems/internal/scripting and a link to this page. In development mode, it also contains the exception message, the script as source and, for an unknown variable or property, its name as missingProperty. The type internal means that the gateway could not complete the processing of the exchange, and the subtype scripting points to a script. In production mode, the title is replaced by Internal Server Error, the type is shortened to https://membrane-api.io/problems/internal and the details are left out.

How the Groovy Plugin Runs Scripts

The groovy plugin runs a script in the request or response flow. The script can use variables such as message, header, params, json, exc and properties, and return CONTINUE, RETURN or ABORT. See scripting for an overview. If the script throws, Membrane stops the flow and answers with this error.

Common Causes

A Variable or Property Does Not Exist

A MissingPropertyException names the unknown variable in missingProperty. Typical cases are a typo in a variable name, json when the body is not valid JSON or is not declared as JSON, and params in the response flow or when the query string could not be parsed.

A Method Is Missing or Called on Null

The script calls a method that does not exist on the object (MissingMethodException), or a method on null (NullPointerException), for example on a header that the message does not have.

The Script or an API Throws an Exception

The script throws an exception on purpose, or a Java or Groovy API it calls throws one, for example a failed number conversion.

Compile Errors Are Reported Elsewhere

A script that does not compile does not lead to this error. It is reported as a configuration error when the gateway starts.

How to Fix It

  1. Read missingProperty, the exception message and source in the response (development mode). The log contains the message and the script at warn level.
  2. Guard against missing input, for example with the Elvis operator ?: or the null-safe operator ?.. Check message.isJSON() before you use json.
  3. If the error comes from invalid client input, validate it earlier in the flow, for example with an OpenAPI document. The client then gets a 400 instead of this 500.

A script that tolerates a missing header:

api:
port: 2000
flow:
- request:
- groovy:
src: |
def id = header.getFirstValue('X-Id') ?: 'default'
exc.setProperty('id', id)
CONTINUE

target:
url: https://api.predic8.de
api:
  port: 2000
  flow:
    - request:
        - groovy:
            src: |
              def id = header.getFirstValue('X-Id') ?: 'default'
              exc.setProperty('id', id)
              CONTINUE
  target:
    url: https://api.predic8.de

End the script with CONTINUE: if a script returns a string, Membrane uses it as the message body.

Hide Details in Production

By default, Membrane runs in development mode and adds details to error responses that help you find the problem. These details may reveal information about your setup. In production, turn them off:

configuration:
production: true
configuration:
  production: true

Add the configuration document to your apis.yaml and separate it from the APIs with ---. The title then reads Internal Server Error, and instead of the details the response only contains a log key. Search the gateway log for this key to find the exception.

Related Documentation

Configuration reference:

Tutorials with runnable examples:

← All Membrane error messages

Still stuck? See the troubleshooting guide or ask on GitHub Issues. For commercial support, contact info@predic8.de.