---
title: Read pipeline logs
description: Read Azure DevOps build logs with the SAIF CLI, preserve build context, and compare failing steps with earlier jobs.
---

# Read pipeline logs

Use `saif pipeline logs <build>` to read logs without rerunning a build. Start with the failing step, then inspect earlier jobs in the same run when a later lookup says a resource or artifact does not exist.

## Reading Build Logs from the CLI

| Mode | Input | Context |
| --- | --- | --- |
| Remote | Full build URL | The URL supplies the host, collection, project, and build ID |
| Contextual | Build ID | Repository selector, explicit coordinates, current repository, or interactive selection |

### Remote mode (by URL)

Paste the build URL from the browser:

```powershell
saif pipeline logs "https://dev.azure.com/SAIFCorporation/Customer/_build/results?buildId=162774"
```

Do not combine a URL with `--host`, `--collection`, `--project`, or `--repo`; remote mode already has its coordinates and rejects those context flags.

A URL copied from a stage, job, or step can include `si`, `j`, or `t`. Those identifiers scope the output to that node. Use `--all-steps` to remove the URL-derived scope and inspect the whole build:

```powershell
saif pipeline logs "https://dev.azure.com/SAIFCorporation/Customer/_build/results?buildId=162774" --all-steps
```

For example, if Terraform apply fails, inspect the preceding **Check Terraform Cloud Workspace Existence** step before assuming the workspace is missing. The check logs the resolved workspace name and ID. Compare them with the apply step's target and error; a successful existence check rules out that particular missing-workspace diagnosis, not every later Terraform failure.

### Contextual mode (by id)

From a repository clone, the CLI can infer context from its git remote. Outside a clone, select a repository or provide coordinates:

```powershell
saif pipeline logs 162774
saif pipeline logs 162774 --repo my-service
saif pipeline logs 162774 --host dev.azure.com --collection SAIFCorporation
```

`saif pipeline monitor <build-id>` resolves a bare build ID through the same context resolution, so it also infers the repository from the current clone.

### Filtering and output

```powershell
# Only failed steps
saif pipeline logs 162774 --status failed

# Scope to a stage and step
saif pipeline logs 162774 --stage Build --step Compile

# Last 50 lines across matching steps
saif pipeline logs 162774 --tail 50

# Structured output
saif pipeline logs 162774 --format json
```

Filters are case-insensitive and combinable. `--stage`, `--job`, and `--step` accept a name or timeline-record GUID; `--stage` also accepts the stage's YAML identifier. Explicit filters override the corresponding URL-derived scope. `--all-steps` ignores URL scope, not filters you explicitly supplied.

For a running build, `--follow` streams new lines until completion. It cannot combine with `--tail` or machine-readable output (`json`, `jsonlines`, or `plain`). A log command can return a failure exit code because the selected build steps failed, even when it successfully retrieved their logs.

## Compare earlier and later jobs

1. Identify the first failing operation: initialization, checkout, restore/build, test, or deployment.
2. If it consumes a resource from an earlier job, read that job's result and recorded identifier.
3. Compare environment, workspace, resource name, and lookup filter. A successful create followed by an empty lookup suggests a lookup or timing problem, not proof that creation never ran.
4. Preserve the build URL and relevant error before changing configuration. Redact tokens and sensitive log values before sharing.

See [Troubleshooting](../troubleshoot/index.md) for symptom-specific articles, and [Pipelines](pipelines.md) for the pipeline and variable contracts.

Command behavior comes from [`PipelineLogsCommand`](https://github.com/saif-corp/forge/blob/main/src/dotnet/SAIF.Platform.CLI/Commands/Pipeline/PipelineLogsCommand.cs). Use `saif pipeline logs --help` for the installed CLI's complete option surface.
