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.
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:
@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.The result is defined as the return value of the default function of the executed script.
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.
Every script must export a default async function. The runtime calls this function when the task runs.
export default async function () {// your logic herereturn { myValue: 42 };}
To fail a Run JavaScript task intentionally, throw an unhandled exception:
export default async function() {throw new Error();}
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.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);}
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);}
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}
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.
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.
Go to
Settings > General > External requests.
Select New host pattern.
Add the domain names.
Select Add.
This way you can granularly control the web services your functions can connect to.
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.
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.
Go to
Settings > General > External requests.
Select New host pattern.
Add the domain names.
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).
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.
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.
Go to
Settings > General > External requests.
Select New host pattern.
Add the domain names.
Select Add.
This way you can granularly control the web services your functions can connect to.
Add a snippet like the following to your JavaScript action to parse the XML and convert it to JSON.
// Load the XML parser from ESMimport xml2js from "https://esm.sh/xml2js@0.6.2";export default async function() {// Dummy XML, can be fetched from your back-endconst 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.
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:
Tasks that have a newer major version available show a New major version available hint.
Don't return secrets as part of the task result. Execution results are visible to anyone with read access to the workflow.