Try it free

Run JavaScript action for Workflows

  • Latest Dynatrace
  • Reference
  • 6-min read

The Run JavaScript action lets you add custom logic to a workflow. Use it to call Dynatrace APIs or external services or transform and enrich data between tasks.

The JavaScript action is not available for simple workflows.

Scripts run in the Dynatrace JavaScript runtime with built-in access to workflow context, previous task results, and loop item values without using Jinja expressions.

Requirements and limitations

The JavaScript runtime imposes general restrictions on functions — including a 120-second timeout and 256 MB RAM limit.

The following additional restrictions apply specifically to workflow tasks:

  • The task result size is limited to 6 MB.
  • JavaScript tasks run without an app context. Accessing Credential Vault secrets requires specific credential settings. For more information, see Credential Vault secrets.
  • Some Dynatrace SDK packages, for example, @dynatrace-sdk/platform/app-environment and @dynatrace-sdk/navigation, require an app or browser context and aren't available in the workflow JavaScript runtime. To resolve the current tenant URL, use a relative URL fetch (fetch("/api/v2/...")) instead of the platform SDK.

Run JavaScript action

Inputs

  • Script: JavaScript code to execute.
  • sdkMajorVersions: Dynatrace SDK package names and the selected major version.

Result

The result is defined as the return value of the default function of the executed script.

Best practices for the Run JavaScript action

The following sections cover how to create effective and secure JavaScript actions: structuring your script, accessing workflow context and previous task results, passing data to downstream tasks, making HTTP requests, using Credential Vault secrets, importing third-party libraries, and pinning SDK versions.

Write your script

Every script must export a default async function. The runtime calls this function when the task runs.

export default async function () {
// your logic here
return { myValue: 42 };
}

Intentionally fail a task

To fail a Run JavaScript task intentionally, throw an unhandled exception:

export default async function() {
throw new Error();
}

Access workflow context

Execution identifiers

The runtime injects workflow and task identifiers into the function parameters:

export default async function ({ executionId, actionExecutionId }) {
console.log('Workflow execution id: ', executionId);
console.log('Action execution id: ', actionExecutionId);
}

You can also import these values from the @dynatrace-sdk/automation-utils package:

import { actionExecutionId, executionId, taskName, workflowId } from '@dynatrace-sdk/automation-utils';
export default async function () {
console.log(`Running action execution '${actionExecutionId}' for task '${taskName}' of workflow '${workflowId}' in workflow execution '${executionId}'`);
}

The available context properties are:

  • workflowId: The executed workflow's ID.
  • executionId: The ID of the related workflow execution.
  • actionExecutionId: The ID of the current action execution.
  • taskName: The task's name in the workflow execution.

Results from previous tasks

Use the automation-utils SDK for a concise way to retrieve a predecessor task's result:

import { result } from '@dynatrace-sdk/automation-utils';
export default async function () {
const myResult = await result('my_task');
console.log('The whole result object: ', myResult);
console.log('Only one variable: ', myResult.myVariable);
}

For full access to the Automation API, use the client-automation SDK instead:

import { executionsClient } from '@dynatrace-sdk/client-automation';
export default async function ({ executionId }) {
const config = { executionId, id: 'my_task' };
const myResult = await executionsClient.getTaskExecutionResult(config);
console.log('My task result: ', myResult);
console.log('Only one variable: ', myResult.myVariable);
}

Current loop item

When a task is configured to loop, use loopItemValue to access the value for the current iteration:

export default async function ({ loopItemValue }) {
console.log(loopItemValue);
}

Event trigger payload

For workflows triggered by an event, retrieve the event payload from the execution:

import { execution } from '@dynatrace-sdk/automation-utils';
export default async function () {
const ex = await execution();
console.log(ex.params.event);
// your code goes here
}

Pass output to downstream tasks

The return value of a JavaScript task is accessible in subsequent tasks using Jinja expressions. Use {{ result("task_name")["property"] }} to reference a specific property from the task output.

If your JavaScript task returns an object:

export default async function () {
return { newJobs: ["job1", "job2"], count: 2 };
}

A downstream task can reference the result using these expressions:

  • {{ result("run_javascript_1")["newJobs"] }}: the full array.
  • {{ result("run_javascript_1")["count"] }}: a specific property.
  • {{ result("run_javascript_1")["newJobs"] | default([]) }}: with a fallback when the property is absent.

To verify available outputs before running the workflow, use the expression preview in the task editor. Enter the expression and select Preview to evaluate it against the latest task result.

A task can reference only the outputs of its direct predecessors in the workflow graph. If the producing task is not a direct predecessor, the expression resolves to Undefined variables at runtime.

Make HTTP requests

Use the Fetch API to call Dynatrace APIs or external endpoints from a JavaScript task.

Relative URLs (Dynatrace APIs): Use relative paths, for example /api/v2/entities, to call Dynatrace APIs. The runtime automatically attaches the required authentication headers.

Don't set a custom Authorization header on relative URL requests. The runtime overwrites it, which causes a 403 error.

Absolute URLs (external endpoints): Use the full URL and provide your own bearer token or API key. The external endpoint must be added to External requests.

External requests enable outbound network connections from your Dynatrace environment to external services. They allow you to control access to public endpoints from the AppEngine with app functions and functions in Dashboards, Notebooks, and Automations.

  1. Go to Settings Settings > General > External requests.

  2. Select New host pattern.

  3. Add the domain names.

  4. Select Add.

This way you can granularly control the web services your functions can connect to.

Credential Vault secrets

To use a Credential Vault secret in a script, for example, as an API key in an HTTP request, retrieve it with credentialVaultClient and use it directly without storing it in the task result.

import { credentialVaultClient } from '@dynatrace-sdk/client-classic-environment-v2';
export default async function () {
const credential = await credentialVaultClient.getCredentialsDetails({ id: 'CREDENTIALS_VAULT-XXXXXXXXXXXX' });
const token = credential.token;
const response = await fetch('https://example.com/api/resource', {
method: 'GET',
headers: { 'X-API-Key': token },
});
// Do not include the token or other credential material in the task result —
// execution results are visible to anyone with read access to the workflow.
return response.json();
}

The following credential settings are required.

  • The AppEngine scope is selected.
  • Allow access without app context is turned on.
  • The workflow actor has access to the credential.

Import third-party libraries

To use a third-party library, import it via a URL.

Restrictions apply:

  • The JavaScript modules need to be valid ECMAScript modules.

  • They run within the context of the Dynatrace JavaScript runtime, and its respective compatibility.

  • Only modules from allowlisted URLs can be loaded. You need to add them to External requests.

    External requests enable outbound network connections from your Dynatrace environment to external services. They allow you to control access to public endpoints from the AppEngine with app functions and functions in Dashboards, Notebooks, and Automations.

    1. Go to Settings Settings > General > External requests.

    2. Select New host pattern.

    3. Add the domain names.

    4. Select Add.

    This way you can granularly control the web services your functions can connect to.

  • Imports may not exceed 6 MB in size (combined).

Example — use XMLJSON library to parse XML input

If your backend produces legacy XML output but you need to process data as JSON, use a library like XML2JSON rather than writing your own parser.

  1. Add the XMLJSON library URL to the allowed External requests.

    External requests enable outbound network connections from your Dynatrace environment to external services. They allow you to control access to public endpoints from the AppEngine with app functions and functions in Dashboards, Notebooks, and Automations.

    1. Go to Settings Settings > General > External requests.

    2. Select New host pattern.

    3. Add the domain names.

    4. Select Add.

    This way you can granularly control the web services your functions can connect to.

  2. Add a snippet like the following to your JavaScript action to parse the XML and convert it to JSON.

// Load the XML parser from ESM
import xml2js from "https://esm.sh/xml2js@0.6.2";
export default async function() {
// Dummy XML, can be fetched from your back-end
const xml = "<root><list><item>Hello</item><item>World</item></list></root>";
const parser = new xml2js.Parser();
const json = await parser.parseStringPromise(xml);
return json;
}

Package CDNs like esm.sh, unpkg, JSR, JSDELIVR, or Deno offer compatible packages.

Note that some libraries depend on Node.js built-in modules — such as net, tls, fs, or crypto — that the Dynatrace JavaScript runtime does not provide. Libraries that require low-level socket or filesystem access (for example, Kafka clients like KafkaJS) will fail to load. See JavaScript runtime for the full compatibility details.

Dynatrace SDK version pinning

In a Run JavaScript action, you can pin each Dynatrace SDK package to a specific major version to control when your action adopts breaking changes. Minor and patch updates within the selected major version are applied automatically.

The Dynatrace SDK versions section in the task editor shows each available package and its currently selected major version.

Pinning affects only the version of packages you directly import. If an imported package has its own dependencies, those resolve according to the package's own dependency definition.

When you add a new Run JavaScript task, the latest major version of the SDK is selected by default.

Tasks created before this feature was introduced, or that omit the sdkMajorVersions input, default to the oldest available major version. When you open such a task, the editor shows a warning. Select Configure package versions to load the available versions and explicitly set them.

To upgrade or roll back an SDK package:

  1. Open the task in the editor.
  2. Expand Dynatrace SDK versions.
  3. Select the desired major version from the dropdown for each package.

Tasks that have a newer major version available show a New major version available hint.

Security

  • The Run JavaScript action does not support expressions in its input to avoid the possibility of code injection.
  • All HTTP calls are validated against the global allowlist.
  • If you import third-party libraries, the allowlisted CDN domains provide access to the entire package portfolio. The Dynatrace JavaScript runtime is robust against certain attack vectors, but you might accidentally allow malicious code. Mirror dependencies in your internal infrastructure and monitor their security implications with Dynatrace Application Security or third-party tools like Snyk.

Don't return secrets as part of the task result. Execution results are visible to anyone with read access to the workflow.

Related tags
Dynatrace Platform