Reported by the cattbox manager, verified against this repo's tags by the dispatcher. Filed here because it affects every repo in the org: CODE_STYLEGUIDE_GO.md mandates this library for all Go repos.
The deadlock
JSONHandler — selected whenever stdout is not a TTY, i.e. every container and every CI run — writes via the stdlib log package. slog.SetDefault redirects stdlib log back into the same handler. The first log line recurses and deadlocks on the stdlib logger's mutex.
cattbox's make test hung to its 30s timeout with exactly that cycle in the trace.
This is not a degradation, it is a hang. A binary using v1.0.0stops on its first log statement in production, while passing a developer's local run — because an interactive terminal selects ConsoleHandler instead. Local green, container hang.
Why the fix is unreachable
Tags on this repo, read from the API just now:
1.0.1 9121da9aaed27db195db998185e7f215c143fd3e <- the fix, NOT resolvable by Go
v1.0.0 31c9ed52cb8f68d690dc57caecc1b8f7a0e5f0bc <- the deadlocking version
Go requires the leading v for a semver tag, so 1.0.1 is invisible to the module proxy. v1.0.0 is the only version go get sneak.berlin/go/simplelog can resolve, which means the obvious command hands every consumer the deadlocking release.
Fix
One command, and it unblocks every consuming repo at once:
git tag v1.0.1 9121da9aaed2 && git push origin v1.0.1
Nothing else changes — same commit, additional tag. Note the dispatcher can create this tag via the Gitea API on request, but has not done so unilaterally, since publishing a version tag changes what every downstream repo resolves and that is the owner's call.
Interim workaround for consuming repos
Pin the pseudo-version naming the fix commit, rather than go get:
Same module, hash recorded in go.sum, no vendoring and no hand-rolled substitute. cattbox is using exactly this today (its #25 tracks bumping to a real tag once one exists).
Definition of done
v1.0.1 exists and go get sneak.berlin/go/simplelog@v1.0.1 resolves the fix commit.
A consuming repo demonstrates a log line emitted from a non-TTY context without hanging — a container run, not a local terminal, since a TTY takes the other code path and cannot reproduce the bug.
Consuming repos that pinned the pseudo-version are told they can move to the tag.
Reported by the cattbox manager, verified against this repo's tags by the dispatcher. Filed here because it affects every repo in the org: `CODE_STYLEGUIDE_GO.md` mandates this library for all Go repos.
## The deadlock
`JSONHandler` — selected whenever stdout is not a TTY, i.e. **every container and every CI run** — writes via the stdlib `log` package. `slog.SetDefault` redirects stdlib `log` back into the same handler. The first log line recurses and deadlocks on the stdlib logger's mutex.
cattbox's `make test` hung to its 30s timeout with exactly that cycle in the trace.
This is not a degradation, it is a hang. A binary using `v1.0.0` **stops on its first log statement in production**, while passing a developer's local run — because an interactive terminal selects `ConsoleHandler` instead. Local green, container hang.
## Why the fix is unreachable
Tags on this repo, read from the API just now:
```
1.0.1 9121da9aaed27db195db998185e7f215c143fd3e <- the fix, NOT resolvable by Go
v1.0.0 31c9ed52cb8f68d690dc57caecc1b8f7a0e5f0bc <- the deadlocking version
```
Go requires the leading `v` for a semver tag, so `1.0.1` is invisible to the module proxy. **`v1.0.0` is the only version `go get sneak.berlin/go/simplelog` can resolve**, which means the obvious command hands every consumer the deadlocking release.
## Fix
One command, and it unblocks every consuming repo at once:
```sh
git tag v1.0.1 9121da9aaed2 && git push origin v1.0.1
```
Nothing else changes — same commit, additional tag. Note the dispatcher can create this tag via the Gitea API on request, but has not done so unilaterally, since publishing a version tag changes what every downstream repo resolves and that is the owner's call.
## Interim workaround for consuming repos
Pin the pseudo-version naming the fix commit, rather than `go get`:
```
sneak.berlin/go/simplelog v1.0.1-0.20260208172955-9121da9aaed2
```
Same module, hash recorded in `go.sum`, no vendoring and no hand-rolled substitute. cattbox is using exactly this today (its #25 tracks bumping to a real tag once one exists).
## Definition of done
- `v1.0.1` exists and `go get sneak.berlin/go/simplelog@v1.0.1` resolves the fix commit.
- A consuming repo demonstrates a log line emitted from a non-TTY context without hanging — a container run, not a local terminal, since a TTY takes the other code path and cannot reproduce the bug.
- Consuming repos that pinned the pseudo-version are told they can move to the tag.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Reported by the cattbox manager, verified against this repo's tags by the dispatcher. Filed here because it affects every repo in the org:
CODE_STYLEGUIDE_GO.mdmandates this library for all Go repos.The deadlock
JSONHandler— selected whenever stdout is not a TTY, i.e. every container and every CI run — writes via the stdliblogpackage.slog.SetDefaultredirects stdliblogback into the same handler. The first log line recurses and deadlocks on the stdlib logger's mutex.cattbox's
make testhung to its 30s timeout with exactly that cycle in the trace.This is not a degradation, it is a hang. A binary using
v1.0.0stops on its first log statement in production, while passing a developer's local run — because an interactive terminal selectsConsoleHandlerinstead. Local green, container hang.Why the fix is unreachable
Tags on this repo, read from the API just now:
Go requires the leading
vfor a semver tag, so1.0.1is invisible to the module proxy.v1.0.0is the only versiongo get sneak.berlin/go/simplelogcan resolve, which means the obvious command hands every consumer the deadlocking release.Fix
One command, and it unblocks every consuming repo at once:
Nothing else changes — same commit, additional tag. Note the dispatcher can create this tag via the Gitea API on request, but has not done so unilaterally, since publishing a version tag changes what every downstream repo resolves and that is the owner's call.
Interim workaround for consuming repos
Pin the pseudo-version naming the fix commit, rather than
go get:Same module, hash recorded in
go.sum, no vendoring and no hand-rolled substitute. cattbox is using exactly this today (its #25 tracks bumping to a real tag once one exists).Definition of done
v1.0.1exists andgo get sneak.berlin/go/simplelog@v1.0.1resolves the fix commit.clawbot referenced this issue2026-09-03 15:06:57 +02:00