Skill Tracer
Skills › Scientific Agent Skills › latchbio-integration › operations-and-debugging.md

operations-and-debugging.md

355 lines · skills/latchbio-integration/references/operations-and-debugging.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Operations, Registration, Debugging, and Execution
2
3This reference targets the current stable CLI and SDK (`latch==2.77.1`).
4

Operations, Registration, Debugging, and Execution

This reference targets the current stable CLI and SDK (latch==2.77.1).

Raw lines 1 to 4
5## Authenticate and Select a Workspace
6
7```bash
8latch login
9latch workspace
10```
12Select a known workspace by numeric ID:
14```bash
15latch workspace --id 12345
16```
18The active workspace controls unqualified `latch:///` paths, Registry access,
19workflow registration, and programmatic execution. Surface it before a
20destructive or costly action.
22Do not read or print `~/.latch/token`. Use the CLI's supported login and token
23handling.

Authenticate and Select a Workspace

latch login
latch workspace

Select a known workspace by numeric ID:

latch workspace --id 12345

The active workspace controls unqualified latch:/// paths, Registry access, workflow registration, and programmatic execution. Surface it before a destructive or costly action.

Do not read or print ~/.latch/token. Use the CLI's supported login and token handling.

Raw lines 5 to 24
25## Registration
27Basic remote registration:
29```bash
30latch register --yes --open .
31```
33Remote builds are the default:
35```bash
36latch register --remote .
37```
39Use a local Docker build only when intentional:
41```bash
42latch register --no-remote .
43```
45Important options:
47```bash
48# Register into another workspace
49latch register --workspace-id 12345 .
51# Mark the version as a release
52latch register --mark-as-release .
54# Register workflows from a non-default Python module
55latch register --workflow-module wf.custom_entrypoint .
57# Use a specific Dockerfile
58latch register --dockerfile Dockerfile.release .
60# Plain build output for CI logs
61latch register --docker-progress plain .
62```

Registration

Basic remote registration:

latch register --yes --open .

Remote builds are the default:

latch register --remote .

Use a local Docker build only when intentional:

latch register --no-remote .

Important options:

# Register into another workspace
latch register --workspace-id 12345 .

# Mark the version as a release
latch register --mark-as-release .

# Register workflows from a non-default Python module
latch register --workflow-module wf.custom_entrypoint .

# Use a specific Dockerfile
latch register --dockerfile Dockerfile.release .

# Plain build output for CI logs
latch register --docker-progress plain .
Raw lines 25 to 63
64### Version behavior
66Registration combines the project `version` with automatic content/version
67information unless disabled. Do not disable automatic versioning merely to
68force an overwrite.
70An ordinary duplicate workflow registration exits with status `2`. A duplicate
71**staging** version exits with status `1`, which also covers build failures;
72inspect the diagnostic instead of applying the ordinary-registration exit-code
73rule to staging.

Version behavior

Registration combines the project version with automatic content/version information unless disabled. Do not disable automatic versioning merely to force an overwrite.

An ordinary duplicate workflow registration exits with status 2. A duplicate staging version exits with status 1, which also covers build failures; inspect the diagnostic instead of applying the ordinary-registration exit-code rule to staging.

Raw lines 64 to 74
75### Release behavior
77Before `--mark-as-release`:
79- Pin SDK, Python, system, and scientific dependencies.
80- Record tool and database versions.
81- Run a representative launch plan.
82- Confirm result links and metadata.
83- Verify the source commit is clean and reproducible.

Release behavior

Before --mark-as-release:

  • Pin SDK, Python, system, and scientific dependencies.
  • Record tool and database versions.
  • Run a representative launch plan.
  • Confirm result links and metadata.
  • Verify the source commit is clean and reproducible.
Raw lines 75 to 84
85## Private Workflow Images
87SDK 2.77.1 supports an explicit workspace for image upload and listing:
89```bash
90latch image ls --workspace-id 12345
91latch image upload my-workflow:1.0 --workspace-id 12345 --yes
92```
94Upload expects the image to exist in the local Docker daemon. To fetch an image
95intentionally, add `--pull` and use its full trusted registry reference. Since
962.77.0, a missing local image is no longer pulled implicitly.
98An upload exits `0` when the push and Latch record both succeed, `1` when the
99push fails, and `3` when the image was pushed but recording it in Latch failed.
100The record is idempotent, so retry the same reference/name/version after status
101`3`; an immutable registry tag can require a new version on retry. Preserve the
102reported digest to identify the exact uploaded image. An empty
103`latch image ls` result is a successful exit `0`; status messages use stderr.

Private Workflow Images

SDK 2.77.1 supports an explicit workspace for image upload and listing:

latch image ls --workspace-id 12345
latch image upload my-workflow:1.0 --workspace-id 12345 --yes

Upload expects the image to exist in the local Docker daemon. To fetch an image intentionally, add --pull and use its full trusted registry reference. Since 2.77.0, a missing local image is no longer pulled implicitly.

An upload exits 0 when the push and Latch record both succeed, 1 when the push fails, and 3 when the image was pushed but recording it in Latch failed. The record is idempotent, so retry the same reference/name/version after status 3; an immutable registry tag can require a new version on retry. Preserve the reported digest to identify the exact uploaded image. An empty latch image ls result is a successful exit 0; status messages use stderr.

Raw lines 85 to 104
105## Staging and Development Shell
107Build an image without publishing a workflow version:
109```bash
110latch register --staging .
111```
113In 2.77.1, the staging branch ignores `--workspace-id` and uses the active
114workspace. Select the target using `latch workspace --id 12345` before staging.
115It also does not generate entrypoints from `--nf-script` or `--snakefile`;
116prepare the version-compatible entrypoint first.
118Open a remote interactive shell in that image:
120```bash
121latch develop .
122```
124Choose a development instance:
126```bash
127latch develop . --instance-size small_gpu_task
128```
130Use `latch develop --help` to inspect the installed version's supported sizes.

Staging and Development Shell

Build an image without publishing a workflow version:

latch register --staging .

In 2.77.1, the staging branch ignores --workspace-id and uses the active workspace. Select the target using latch workspace --id 12345 before staging. It also does not generate entrypoints from --nf-script or --snakefile; prepare the version-compatible entrypoint first.

Open a remote interactive shell in that image:

latch develop .

Choose a development instance:

latch develop . --instance-size small_gpu_task

Use latch develop --help to inspect the installed version's supported sizes.

Raw lines 105 to 131
132### Sync behavior
134- Local files under the workflow root are synced into the container.
135- Files outside that root are not synced.
136- Local updates overwrite corresponding container files.
137- Local deletions do not remove existing container files.
138- Container-side edits are not synced back and can be overwritten.
139- `.gitignore` and `.dockerignore` are respected.
140- Re-run staging registration after changing the Dockerfile or dependencies.
142Place small test fixtures under the project root and exclude private or large
143data from registration archives.

Sync behavior

  • Local files under the workflow root are synced into the container.
  • Files outside that root are not synced.
  • Local updates overwrite corresponding container files.
  • Local deletions do not remove existing container files.
  • Container-side edits are not synced back and can be overwritten.
  • .gitignore and .dockerignore are respected.
  • Re-run staging registration after changing the Dockerfile or dependencies.

Place small test fixtures under the project root and exclude private or large data from registration archives.

Raw lines 132 to 144
145## Debug a Running Task
147Open an interactive shell for an execution or task:
149```bash
150latch exec --execution-id <execution-id>
151```
153For a Nextflow work directory:
155```bash
156latch nextflow attach --execution-id <execution-id>
157```
159Use interactive access for diagnosis, not for modifying the source of record.
160Reproduce and fix the issue locally, then register a new version.

Debug a Running Task

Open an interactive shell for an execution or task:

latch exec --execution-id <execution-id>

For a Nextflow work directory:

latch nextflow attach --execution-id <execution-id>

Use interactive access for diagnosis, not for modifying the source of record. Reproduce and fix the issue locally, then register a new version.

Raw lines 145 to 161
162## Programmatic Execution
164The old `latch launch` CLI is deprecated. Use
165`latch_cli.services.launch.launch_v2`.

Programmatic Execution

The old latch launch CLI is deprecated. Use latch_cli.services.launch.launch_v2.

Raw lines 162 to 166
167### Launch with Python parameters
169```python
170import asyncio
172from latch.types import LatchFile
173from latch_cli.services.launch.launch_v2 import launch
175execution = launch(
176 wf_name="my_workflow",
177 version="1.2.3-abcd12",
178 params={
179 "reads": LatchFile("latch:///test-data/reads.fastq.gz"),
180 "minimum_quality": 20,
181 },
184completed = asyncio.run(asyncio.wait_for(execution.wait(), timeout=3600))
185if completed is None:
186 raise RuntimeError("execution polling ended without a result")
187if completed.status != "SUCCEEDED":
188 raise RuntimeError(
189 f"execution {completed.id} ended with {completed.status}"
190 )
192print(completed.output)
193print([path.path for path in completed.ingress_data])
194```
196The timeout limits asynchronous polling; synchronous SDK network requests may
197exceed it. A local polling timeout does **not** cancel paid compute: retain the
198execution ID, check status in the Console, and explicitly abort only if intended.
200Only use this API with trusted registered workflow definitions: typed metadata
201is deserialized by the SDK, including when `best_effort=True`.
203`wf_name` is the registered workflow name (check `.latch/workflow_name` or the
204Console), not the human-readable metadata display name.
206`launch` defaults `best_effort=True`, allowing compatible dictionaries,
207dataclasses, strings for enum values, and other schema-guided conversions.
208Set `best_effort=False` only when the caller imports exactly the same Python
209types as the registered workflow.
211Compatibility:
213- Programmatic launch requires workflows registered with SDK 2.62.0+.
214- Typed output decoding requires workflows registered with SDK 2.65.1+.
215- Python versions and imported classes must remain compatible for strict
216 serialized type decoding.

Launch with Python parameters

import asyncio

from latch.types import LatchFile
from latch_cli.services.launch.launch_v2 import launch

execution = launch(
    wf_name="my_workflow",
    version="1.2.3-abcd12",
    params={
        "reads": LatchFile("latch:///test-data/reads.fastq.gz"),
        "minimum_quality": 20,
    },
)

completed = asyncio.run(asyncio.wait_for(execution.wait(), timeout=3600))
if completed is None:
    raise RuntimeError("execution polling ended without a result")
if completed.status != "SUCCEEDED":
    raise RuntimeError(
        f"execution {completed.id} ended with {completed.status}"
    )

print(completed.output)
print([path.path for path in completed.ingress_data])

The timeout limits asynchronous polling; synchronous SDK network requests may exceed it. A local polling timeout does not cancel paid compute: retain the execution ID, check status in the Console, and explicitly abort only if intended.

Only use this API with trusted registered workflow definitions: typed metadata is deserialized by the SDK, including when best_effort=True.

wf_name is the registered workflow name (check .latch/workflow_name or the Console), not the human-readable metadata display name.

launch defaults best_effort=True, allowing compatible dictionaries, dataclasses, strings for enum values, and other schema-guided conversions. Set best_effort=False only when the caller imports exactly the same Python types as the registered workflow.

Compatibility:

  • Programmatic launch requires workflows registered with SDK 2.62.0+.
  • Typed output decoding requires workflows registered with SDK 2.65.1+.
  • Python versions and imported classes must remain compatible for strict serialized type decoding.
Raw lines 167 to 217
218### Launch a registered launch plan
220```python
221import asyncio
223from latch_cli.services.launch.launch_v2 import launch_from_launch_plan
225execution = launch_from_launch_plan(
226 wf_name="my_workflow",
227 version="1.2.3-abcd12",
228 lp_name="Small public example",
231completed = asyncio.run(asyncio.wait_for(execution.wait(), timeout=3600))
232if completed is None or completed.status != "SUCCEEDED":
233 raise RuntimeError("launch-plan execution did not succeed")
234```

Launch a registered launch plan

import asyncio

from latch_cli.services.launch.launch_v2 import launch_from_launch_plan

execution = launch_from_launch_plan(
    wf_name="my_workflow",
    version="1.2.3-abcd12",
    lp_name="Small public example",
)

completed = asyncio.run(asyncio.wait_for(execution.wait(), timeout=3600))
if completed is None or completed.status != "SUCCEEDED":
    raise RuntimeError("launch-plan execution did not succeed")
Raw lines 218 to 235
236### Poll or abort
238`Execution` exposes:
240- `id`
241- `status`
242- `poll()` (a generator; calling it alone does not fetch status)
243- async `wait()`
244- `abort()`
246Abort only the intended active execution:
248```python
249next(execution.poll()) # Refresh status once; continuous polling needs a delay.
250if execution.status not in {"SUCCEEDED", "FAILED", "ABORTED", "SKIPPED", "ABORTING"}:
251 execution.abort()
252```

Poll or abort

Execution exposes:

  • id
  • status
  • poll() (a generator; calling it alone does not fetch status)
  • async wait()
  • abort()

Abort only the intended active execution:

next(execution.poll())  # Refresh status once; continuous polling needs a delay.
if execution.status not in {"SUCCEEDED", "FAILED", "ABORTED", "SKIPPED", "ABORTING"}:
    execution.abort()
Raw lines 236 to 253
254## Interactive Execution Through MCP
256When Latch MCP is available:
2581. List workspaces.
2592. List workflows.
2603. Fetch the selected workflow schema.
2614. Validate parameters.
2625. Obtain confirmation for paid compute.
2636. Launch.
2647. Poll execution state.
2658. Fetch task logs only for relevant failed or running nodes.
267MCP authorization is separate from SDK login. See
268`references/latch-mcp.md`.

Interactive Execution Through MCP

When Latch MCP is available:

  1. List workspaces.
  2. List workflows.
  3. Fetch the selected workflow schema.
  4. Validate parameters.
  5. Obtain confirmation for paid compute.
  6. Launch.
  7. Poll execution state.
  8. Fetch task logs only for relevant failed or running nodes.

MCP authorization is separate from SDK login. See references/latch-mcp.md.

Raw lines 254 to 269
Uses an outside tool MCP :254
270## Monitoring
272Console execution monitoring provides:
274- Overall execution status
275- Graph and task-node status
276- Inputs and outputs
277- Logs
278- Provenance and result files
279- Resource monitoring
281The 2.77.1 CLI still provides the following deprecated command:
283```bash
284latch get-executions
285```
287The official CLI guide says it will be removed in a future version. Prefer the
288Console or Latch MCP for new monitoring integrations.
290For every production workflow, emit:
292- Concise `message()` calls for actionable warnings and errors
293- Result links for high-value outputs
294- Normal structured logs for detailed diagnostics
296Do not log secrets or signed URLs.

Monitoring

Console execution monitoring provides:

  • Overall execution status
  • Graph and task-node status
  • Inputs and outputs
  • Logs
  • Provenance and result files
  • Resource monitoring

The 2.77.1 CLI still provides the following deprecated command:

latch get-executions

The official CLI guide says it will be removed in a future version. Prefer the Console or Latch MCP for new monitoring integrations.

For every production workflow, emit:

  • Concise message() calls for actionable warnings and errors
  • Result links for high-value outputs
  • Normal structured logs for detailed diagnostics

Do not log secrets or signed URLs.

Raw lines 270 to 297
Uses an outside tool MCP :288
298## Troubleshooting

Troubleshooting

Raw lines 298 to 299
300### Authentication failure
302```bash
303latch login
304latch workspace
305```
307Confirm the workspace is the one containing the data, workflow, and Registry
308objects. Do not attempt to repair authentication by modifying token files.

Authentication failure

latch login
latch workspace

Confirm the workspace is the one containing the data, workflow, and Registry objects. Do not attempt to repair authentication by modifying token files.

Raw lines 300 to 309
310### Registration cannot find the workflow
312- Confirm the workflow root and `wf` package.
313- Check `--workflow-module`.
314- Compile the Python package.
315- Verify metadata imports do not perform network calls.
316- Inspect task-specific Dockerfile arguments; they must be string literals.

Registration cannot find the workflow

  • Confirm the workflow root and wf package.
  • Check --workflow-module.
  • Compile the Python package.
  • Verify metadata imports do not perform network calls.
  • Inspect task-specific Dockerfile arguments; they must be string literals.
Raw lines 310 to 317
318### Build failure
320- Reproduce through staging registration.
321- Use `--docker-progress plain`.
322- Check `.dockerignore` did not omit required files.
323- Confirm system packages and architecture.
324- Use `--no-remote` only when the local Docker environment is known-good.

Build failure

  • Reproduce through staging registration.
  • Use --docker-progress plain.
  • Check .dockerignore did not omit required files.
  • Confirm system packages and architecture.
  • Use --no-remote only when the local Docker environment is known-good.
Raw lines 318 to 325
326### Runtime import or executable failure
328- Enter `latch develop`.
329- Check `which python3`, installed packages, `$PATH`, and executable permissions.
330- Run the task-level test script inside the image.
331- Rebuild staging after dependency changes.

Runtime import or executable failure

  • Enter latch develop.
  • Check which python3, installed packages, $PATH, and executable permissions.
  • Run the task-level test script inside the image.
  • Rebuild staging after dependency changes.
Raw lines 326 to 332
333### Out of memory or storage
335- Inspect resource monitoring.
336- Measure peak rather than average use.
337- Adjust one resource dimension at a time.
338- See `references/resource-configuration.md`.

Out of memory or storage

  • Inspect resource monitoring.
  • Measure peak rather than average use.
  • Adjust one resource dimension at a time.
  • See references/resource-configuration.md.
Raw lines 333 to 339
340### Programmatic launch type error
342- Fetch the workflow's current schema/version.
343- Verify every required parameter.
344- Use `best_effort=True` for compatible external representations.
345- Re-register old workflows with a current SDK when typed outputs are needed.

Programmatic launch type error

  • Fetch the workflow's current schema/version.
  • Verify every required parameter.
  • Use best_effort=True for compatible external representations.
  • Re-register old workflows with a current SDK when typed outputs are needed.
Raw lines 340 to 346
347## Official Sources
349- CLI commands: https://wiki.latch.bio/workflows/sdk/cli/commands
350- Development and debugging: https://wiki.latch.bio/workflows/sdk/testing-and-debugging-a-workflow/development-and-debugging
351- Programmatic execution: https://wiki.latch.bio/workflows/sdk/testing-and-debugging-a-workflow/programmatic-execution
352- Execution monitoring: https://wiki.latch.bio/workflows/sdk/console/execution-monitoring
353- Resource monitoring: https://wiki.latch.bio/workflows/sdk/console/resource-monitoring
354- Versioning: https://wiki.latch.bio/workflows/sdk/console/versioning
355- CLI source in the 2.77.1 release commit: https://github.com/latchbio/latch/blob/b3768e65c6d496868f6e530f11977d857ad85dc7/src/latch_cli/main.py

Official Sources

  • CLI commands: https://wiki.latch.bio/workflows/sdk/cli/commands
  • Development and debugging: https://wiki.latch.bio/workflows/sdk/testing-and-debugging-a-workflow/development-and-debugging
  • Programmatic execution: https://wiki.latch.bio/workflows/sdk/testing-and-debugging-a-workflow/programmatic-execution
  • Execution monitoring: https://wiki.latch.bio/workflows/sdk/console/execution-monitoring
  • Resource monitoring: https://wiki.latch.bio/workflows/sdk/console/resource-monitoring
  • Versioning: https://wiki.latch.bio/workflows/sdk/console/versioning
  • CLI source in the 2.77.1 release commit: https://github.com/latchbio/latch/blob/b3768e65c6d496868f6e530f11977d857ad85dc7/src/latch_cli/main.py
Raw lines 347 to 355