Skip to content
DocsAll docs
Console

Runs

Start a run of a pipeline, pin a version, follow the log of each job, and cancel a run.

Last updated

On this page

Description and operation

General

A run is one execution of one version of a pipeline. A start by hand uses the newest version, or the version that you name. Each run records what it used, so you can see later what ran and why.

FieldMeaning
idThe identity of the run, for example 1760400000000-0a1b2c. Ids sort by start time.
numberThe number of the run for this pipeline, from 1.
pipelineVersion, definitionSha256The version that the run used, and the hash of its definition.
eventWhat started the run: manual, schedule, webhook or pipeline.
requestedByYour handle, or schedule, webhook or pipeline NAME for a trigger.
inputsThe value of each input: the one given, else the default.
environmentThe environment that the start request named, or null.
state, detailThe state of the run, and the cause when it did not succeed. See States.
jobsOne entry for each job and matrix instance, with its own state.
after, triggeredThe run whose end started this run, and the runs that this run started. See After another pipeline.
requestedAtMs, startedAtMs, finishedAtMsThe times, in milliseconds since 1970, when the run was requested, started and ended.
cancelRequestedtrue after a cancel of the run.
claimedBy, leaseExpiresMsThe worker that holds the run, and when its claim lapses.
definitionThe definition of the version. Only a read of one run returns it, while the version exists.

A run keeps the definition that it started with. A later save does not change a run that exists. The full run document is in the pipelines API.

To do these tasks with an AI agent, see Agentic workflows – General.

Start options

OptionMeaning
versionThe version to run. The default is the newest version at the time of the call.
inputsValues for the declared inputs. See Inputs.
environmentRun every job that names no environment in this shared environment.
cloneRun those jobs in a copy of this environment, made for the run. Use only one of environment and clone.

The raw API has no clone key. It takes environment as a name, or as {"clone": "name"}. The SDKs and --clone build the second form.

The start call plans the run at once and answers 202 with the run in queued. If the version cannot run, the call answers 422 with one line for each problem, and records nothing. For environments, see Secrets, registries and environments.

Logs

Each job has one log that holds its output and its error output. The log shows ▶ and the step name before each step, and a last line ■ with the cause when the job did not succeed. You read a log from a byte offset, so a program follows a running job by reading again from next. One answer holds at most 1 MiB. The SDK methods logs and follow do this for you.

A log stops at 8 MiB with the line [log truncated: past 8 MiB]. Secret values in a log show as ***. See Masking.

Cancel

A cancel of a queued run ends it at once. A cancel of a running run sets cancelRequested. The platform then stops each running job and cancels the pending jobs. A cancel of a finished run answers 409.

Retention

The platform deletes a run record 90 days after the run ends. A job log is deleted 90 days after the run started. After that, a read of the log returns the single line log expired: job logs are kept for 90 days.

Tasks

Start a run of a pinned version

Reason for the task: Run a known version of a pipeline, with the inputs and the environment that you choose.

Job set-up

Procedure

  1. Start the run. Leave out version to run the newest version.

    Python
    run = kl.pipelines.run(owner="acme", pipeline="refresh", version=2, inputs={"day": "2026-10-21"})print(run.id, run.pipeline_version, run.state)
    TypeScript
    const run = await kl.pipelines.run({ owner: "acme", pipeline: "refresh", version: 2, inputs: { day: "2026-10-21" } });console.log(run.id, run.doc.pipelineVersion, run.state);
    Go
    run, err := kl.Pipelines.Run(kloudlite.RunPipeline{    Owner: "acme", Pipeline: "refresh", Version: 2,    Inputs: map[string]string{"day": "2026-10-21"},})if err != nil {    log.Fatal(err)}fmt.Println(run.ID, run.PipelineVersion, run.State)
    Ruby
    run = kl.pipelines.run(owner: "acme", pipeline: "refresh", version: 2, inputs: { "day" => "2026-10-21" })puts run.id, run.pipeline_version, run.state
    Java
    var run = kl.pipelines().run(new Kloudlite.RunPipeline().owner("acme").pipeline("refresh").version(2).input("day", "2026-10-21"));System.out.println(run.id() + " " + run.pipelineVersion() + " " + run.state());
    CLI
    kloudlite pipelines run acme/refresh --version 2 --input day=2026-10-21
  2. Add clone="staging" to run the jobs in a copy of the environment staging, or environment="staging" to use it as it is.

Close-out

  1. Make sure that pipelineVersion is 2 and that the state is queued or running.

List the runs of a pipeline

Reason for the task: Find a run, for example the newest run that a schedule started.

Job set-up

Procedure

  1. Show the newest runs. The default is 50 runs, and the maximum is 200.

    Python
    for r in kl.pipelines.runs(owner="acme", pipeline="refresh", limit=10):    print(r.number, r.id, r.event, r.state)
    TypeScript
    for (const r of await kl.pipelines.runs({ owner: "acme", pipeline: "refresh", limit: 10 }))  console.log(r.number, r.id, r.doc.event, r.state);
    Go
    runs, err := kl.Pipelines.Runs(kloudlite.ListRuns{Owner: "acme", Pipeline: "refresh", Limit: 10})if err != nil {    log.Fatal(err)}for _, r := range runs {    fmt.Println(r.Number, r.ID, r.Event, r.State)}
    Ruby
    kl.pipelines.runs(owner: "acme", pipeline: "refresh", limit: 10).each do |r|  puts [r.number, r.id, r.event, r.state].join(" ")end
    Java
    for (var r : kl.pipelines().runs(new Kloudlite.ListRuns().owner("acme").pipeline("refresh").limit(10)))    System.out.println(r.number() + " " + r.id() + " " + r.event() + " " + r.state());
    CLI
    kloudlite pipelines runs acme refresh --limit 10

Close-out

  1. Make sure that the list starts with the newest run.

Show the state of a run and its jobs

Reason for the task: Find out if a run succeeded, and which job or step failed.

Job set-up

Procedure

  1. Read the run, then show its state and the state of each job.

    Python
    run = kl.pipelines.get_run(owner="acme", pipeline="refresh", run="1760400000000-0a1b2c")print(run.state, run.detail)for j in run.jobs:    print(j["key"], j["state"], j.get("failedStep"), j.get("detail"))
    TypeScript
    const run = await kl.pipelines.getRun({ owner: "acme", pipeline: "refresh", run: "1760400000000-0a1b2c" });console.log(run.state, run.doc.detail);for (const j of run.jobs) console.log(j.key, j.state, j.failedStep, j.detail);
    Go
    run, err := kl.Pipelines.GetRun(kloudlite.GetRun{Owner: "acme", Pipeline: "refresh", Run: "1760400000000-0a1b2c"})if err != nil {    log.Fatal(err)}fmt.Println(run.State, run.Detail)for _, j := range run.Jobs {    fmt.Println(j.Key, j.State, j.FailedStep, j.Detail)}
    Ruby
    run = kl.pipelines.get_run(owner: "acme", pipeline: "refresh", run: "1760400000000-0a1b2c")puts run.state, run.detailrun.jobs.each { |j| puts j.values_at("key", "state", "failedStep", "detail").join(" ") }
    Java
    var run = kl.pipelines().getRun(new Kloudlite.GetRun().owner("acme").pipeline("refresh").run("1760400000000-0a1b2c"));System.out.println(run.state() + " " + run.detail());for (var j : run.jobs()) System.out.println(j.get("key") + " " + j.get("state") + " " + j.get("failedStep"));
    CLI
    kloudlite pipelines get-run acme refresh 1760400000000-0a1b2c

Close-out

  1. Make sure that the state is success. If it is failure, read detail of the run and failedStep of the failed job.

Read the log of a job

Reason for the task: Read the output of a job, while it runs or after it ended.

Job set-up

Procedure

  1. Read the whole log of the job load. Use the key of the job, or its index in jobs.

    Python
    print(run.logs(job="load"))
    TypeScript
    console.log(await run.logs({ job: "load" }));
    Go
    out, err := run.Logs("load")if err != nil {    log.Fatal(err)}fmt.Print(out)
    Ruby
    puts run.logs(job: "load")
    Java
    System.out.print(run.logs("load"));
    CLI
    kloudlite pipelines logs acme refresh 1760400000000-0a1b2c load
  2. Read the log of a running job as it grows. The call ends when the job ends.

    Python
    for chunk in run.follow(job="load"):    print(chunk, end="")
    TypeScript
    for await (const chunk of run.follow({ job: "load" })) process.stdout.write(chunk);
    Go
    err = run.Follow(kloudlite.FollowLogs{Job: "load"}, func(chunk string) bool {    fmt.Print(chunk)    return true})if err != nil {    log.Fatal(err)}
    Ruby
    run.follow(job: "load") { |chunk| print chunk }
    Java
    run.follow("load").forEach(System.out::print);
    CLI
    kloudlite pipelines logs acme refresh 1760400000000-0a1b2c load --follow

Close-out

  1. Make sure that the log shows a ▶ line for each step of the job.

Cancel a run

Reason for the task: Stop a run that is not needed, and release its sandboxes.

Job set-up

  • Access: you. For a team, an active member.
  • Conditions: the run is queued or running.
  • References: POST …/runs/{id}/cancel, SDK Run.cancel, Run.wait.

Procedure

  1. Send the cancel, then wait for the run to end.

    Python
    run.cancel()print(run.wait())
    TypeScript
    await run.cancel();console.log(await run.wait());
    Go
    if err := run.Cancel(); err != nil {    log.Fatal(err)}state, err := run.Wait(kloudlite.WaitRun{})if err != nil {    log.Fatal(err)}fmt.Println(state)
    Ruby
    run.cancelputs run.wait
    Java
    run.cancel();System.out.println(run.waitFor());
    CLI
    kloudlite pipelines cancel-run acme refresh 1760400000000-0a1b2ckloudlite pipelines wait-run acme refresh 1760400000000-0a1b2c

Close-out

  1. Make sure that the final state is cancelled, and that no job is running.

Troubleshooting

SymptomPossible causeCorrective action
422 with pipeline refresh cannot run: and a list of linesAn input or a secret is wrong. Each line names the cause.Correct each cause and start again. See Triggers and inputs.
404 with version 2 of refresh is goneThe version was deleted.Start the newest version, or another version that is listed.
400 with environment is emptyenvironment is an empty name, also in {"clone": ""} or --clone.Give the name of an environment.
409 with this run has already finishedThe run ended before the cancel.None. Read the final state of the run.
404 with not found for a runThe id is wrong, or the run belongs to another pipeline. Run records are deleted 90 days after the run ends.Check the owner, the pipeline and the id.
The run stays queuedNo worker has taken the run yet.Wait, then show the run again.
A job shows restarted: the worker running it was lostThe worker that ran the job stopped. Another worker runs the job again from the start.None. Wait for the run to end.
The log is log expired: job logs are kept for 90 daysThe run started more than 90 days ago.None. The run record shows the states.
The log ends with [log truncated: past 8 MiB]The job wrote more than 8 MiB.Write less output, or write large output to a file.
502 with the log could not be readThe log store did not answer.Read the log again.