JetBrains / JetBrains/teamcity-cli
pipeline validate rejects current JetBrains-hosted agent images (Ubuntu-24.04-*) — schema enum only lists legacy names
- Dominant language
- Go
- Stars
- 123
- Forks
- 16
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 22
Description
## Summary
`teamcity pipeline validate` rejects any pipeline whose `runs-on` names a current JetBrains-hosted cloud image (`Ubuntu-24.04-Small`, `Ubuntu-24.04-Medium`, `Ubuntu-24.04-Large-Arm64`, …). The schema bundled with the CLI only knows seven legacy `Linux-*` / `Windows-*` / `Mac-*` names.
These pipelines are valid: they are the live configuration of two production pipelines here, the server accepts them via `pipeline push`, and they build and deploy many times a day on exactly those images.
## Repro
CLI v1.3.0, TeamCity Cloud, server 2026.2 EAP (build 245298).
```yaml
# repro.yaml
jobs:
Build:
runs-on: Ubuntu-24.04-Small
steps:
- type: script
script-content: echo hello
```
```
$ teamcity pipeline validate repro.yaml
✗ repro.yaml has 3 error(s)
Line 3: /jobs/Build/runs-on
value must be one of 'Windows-Small', 'Mac-Medium', 'Linux-XLarge', 'Linux-Large', 'Linux-Medium', 'Linux-Small', 'Windows-Medium'
Line 3: /jobs/Build/runs-on
value must be 'self-hosted'
Line 3: /jobs/Build/runs-on
got string, want object
```
**Expected:** validates clean — `Ubuntu-24.04-Small` is a currently provisioned hosted image.
**Actual:** 3 errors per offending job.
## Root cause
The list is a static enum in the CLI's bundled schema. From `teamcity pipeline schema`, at `/definitions/runOn/anyOf[0]`:
```json
["Windows-Small", "Mac-Medium", "Linux-XLarge", "Linux-Large", "Linux-Medium", "Linux-Small", "Windows-Medium"]
```
No `Ubuntu-24.04-*` entry exists, so every job using the current image family fails.
## Why this matters more than a cosmetic schema gap
The bundled `teamcity-cli` skill tells AI coding agents:
> pipeline push does not validate — always `teamcity pipeline validate` first.
Since a correct pipeline **cannot** validate clean, an agent that follows this instruction sees a failure, attributes it to its own edit, and "fixes" it by changing `runs-on` back to a name in the enum — silently downgrading the job to a legacy agent image. That is a plausible-looking regression an agent will introduce confidently and a reviewer may not catch.
There is no way to tell this false positive from a genuine schema error: same exit code, same error shape. The only reliable workaround is to validate the *unmodified* live config first, record its error count, and treat that as the baseline — which defeats the purpose of the command.
## Suggested fixes (any one resolves it)
1. **Source the image list from the server**, which knows what is actually provisioned, rather than a compile-time enum. This stops the list going stale again.
2. **Downgrade unknown `runs-on` strings to a warning**, not an error — the CLI can't know the full set of a given cloud profile's images.
3. **At minimum, refresh the enum** to include the `Ubuntu-24.04-*` family.
## Minor, related
One problem is reported three times because each `anyOf` branch reports independently (string enum / `self-hosted` / object form). For a plain typo in an image name this triples the noise and buries the useful branch. Reporting only the best-matching branch, or grouping them, would read much better — this matters for agents too, which have to spend context distinguishing three messages describing one fault.
Contributor guide
Research direction
Start with `teamcity pipeline validate` and `teamcity pipeline schema`, inspecting `/definitions/runOn/anyOf[0]` against the `repro.yaml` example. Determine which suggested validation approach fits the CLI, then confirm that a current `Ubuntu-24.04-*` image validates without the three duplicate errors while preserving useful validation for invalid values.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100