Skip to content
Talk to our solutions team

Calling convention

The convention is identical at the CLI and inside a flow’s script: task. A script developed with kis script run moves into automation without a change, and that is deliberate — it is what makes prototyping at the CLI safe.

The default is main:

function main() {
return { ok: true };
}

--func picks another:

Terminal window
kis script run report.js --func summarise 7

A bare return at file scope is a syntax error. The body must be inside a function — the engine calls a named function, it does not evaluate the file.

In Go the entry point must be exported: Main, not main. See Languages.

Data arrives two ways, and they are not interchangeable.

ChannelBecomesSet with
Positional argumentsFunction arguments, in orderafter the filename, or --args
VariablesBare globals, by name--vars k=v, or --env file.yaml
Terminal window
kis script run report.js acme 30 --vars region=us-west-2
function main(customer, days) {
// customer = "acme" days = 30 (positional)
// region = "us-west-2" (bare global)
return { customer, days, region };
}

Arguments are what this call is about; variables are the environment it runs in. A customer id and a day count change per invocation, so they are arguments. A region or an environment name is context every call in that deployment shares, so it is a variable. Getting this the wrong way round produces scripts with eight parameters, most of which never vary.

Terminal window
kis script run x.js anand 7
kis script run x.js --args anand --args 7 # identical

--args appends to whatever positional arguments were given. It exists for the case where a value starts with a dash and would otherwise be read as a flag.

staging.yaml
region: us-west-2
replicas: 3
endpoint: https://api.staging.internal
Terminal window
kis script run deploy.js --env staging.yaml

Each key becomes a bare global. This is the same mechanism as a flow’s vars: block, which is why a script moves between the two unchanged.

Every argument is parsed as JSON, falling back to the raw string when that fails:

Terminal window
kis script run conv.js '[1,2,3]' '{"k":1}'
# a = [1,2,3] (array) b = {k:1} (object)
kis script run conv.js anand 7
# a = "anand" (string) b = 7 (number)

Note the second line: 7 arrives as a number, not a string, because 7 is valid JSON. So does true, and so does null. If you need the string "7", quote it as JSON:

Terminal window
kis script run conv.js '"7"'

The shell quoting is easy to get wrong here — '"7"' passes the four characters "7" to the CLI, which parses them as the JSON string 7.

The return value is the result. Where it goes depends on who called.

At the CLI it is printed with --debug:

$ kis script run report.js --debug
Result: {"count":14,"total":983040}

Without --debug you get the timing line only. The value still exists — it is just not printed, because a script in production returns to a caller rather than to a terminal.

In a flow it lands in setvar, and later nodes read it with {{ }}:

tasks:
- name: pick
script:
language: javascript
file: ./select.js
args: [1048576]
setvar: selection
- name: report
print:
message: "Selected {{selection.count}} artifacts"

Return a map rather than a scalar when there is any chance a caller will want more than one thing later. Adding a field to a returned map breaks nothing; changing a returned number into a map breaks every caller.

Atoms return failure, they do not throw:

function main() {
const r = shell.execute({ script: './deploy.sh', capture: true });
if (!r.success) {
return { ok: false, reason: r.error };
}
return { ok: true, log: r.output };
}

Check success. A script that ignores it returns a cheerful result for work that did not happen, and in a flow that means the next node runs on nothing.

To fail deliberately, throw — the run reports the error rather than a value.

The default is five seconds:

Terminal window
kis script run slow.js --timeout 30000 # milliseconds

Five seconds is right for a transform and wrong for anything reaching the network. Measure before choosing — kis script bench gives a distribution rather than a guess, and a timeout set from a measured p95 is the one that will not fire spuriously at 3am.