Self-referencing value crashes ytt with a Go stack overflow instead of an error
- Dominant language
- Go
- Stars
- 1.9k
- Forks
- 167
- PR merge metrics
- No merged PRs in 30d
Description
**What steps did you take:**
```yaml
#@ def cyc():
#@ x = []
#@ x.append(x)
#@ return x
#@ end
out: #@ cyc()
```
```
ytt -f t.yml
```
**What happened:**
```
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow
```
Exit code 2, no ytt-level error message, after allocating 1 GB of stack. The recursion is `core.StarlarkValue.asInterface` <-> `core.StarlarkValue.itearableAsInterface` in the stack trace. `@ytt:json`'s `json.encode()` on a self-referencing dict fails the same way, and so does `@ytt:yaml`'s `yaml.encode()`.
**What did you expect:**
A normal ytt error naming the offending value, the way other bad inputs are reported. `fatal error` is not recoverable, so an embedding program (`ytt` used as a library) cannot catch it either.
**Anything else you would like to add:**
The Starlark layer already handles this — `str(x)` on the same value returns `'[[...]]'`, so the cycle detection exists one level down and only ytt's own value conversion is missing it:
```yaml
#@ def cyc():
#@ x = []
#@ x.append(x)
#@ return str(x)
#@ end
out: #@ cyc()
```
renders `out: '[[...]]'`.
I am happy to open a PR if you can say which shape you would prefer — a visited-set threaded through `asInterface`, or a plain depth limit. The former needs a signature change on a widely called method, which is why I am asking first rather than guessing.
**Environment:**
- ytt version (use `ytt --version`): 0.55.2 (also reproduced on `main` at 6a94bf4)
- OS: macOS 26.5, arm64
Contributor guide
Research direction
Start with core.StarlarkValue.asInterface and core.StarlarkValue.itearableAsInterface, using the supplied cyclical YAML example and `ytt -f t.yml` to reproduce the failure. Compare this conversion path with the existing cycle handling seen through `str(x)`, and verify that the CLI, `@ytt:json` json.encode(), and `@ytt:yaml` yaml.encode() report a normal ytt error without a Go stack overflow.
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
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100