issue-close.sh: closing comment silently fails — tea issue comment is not a subcommand, and the result is unchecked
#1081
Closed
opened 2026-08-06 20:33:02 +00:00 by Mos
·
1 comment
No Branch/Tag Specified
main
greenfield/fomo-lin
feat/lease-promotion-and-harness-isolation
fix/1099-pipefail-wake
fix/1099-pipefail-tests
fix/1099-pipefail-sweep
fix/framework-shell-portability
fix/1043-pane-git-identity
fix/1081-issue-close-silent-comment-failure
fix/1090-enrollment-wallclock-tolerance
feat/1082-tea-stale-token-diagnostic
fix/detect-platform-silent-128-outside-repo
feat/1050-install-state-machine-red-fixture
fix/pr-merge-message-field
feat/1051-mosaic-brain-installer
feat/1045-mosaic-cred
remediation/state
fix/1056-upgrade-rollback-control-race
fix/1019-ci-queue-timeout-harness
next
feat/rm-02-gate-registry
fix/rm-01-reproducible-checkout
remediation/mission-setup
fix/hygiene-inert-format-gate
fix/1019-queue-guard-stdin
feat/mos-ste-writing-standard
fix/1007-suite-hermeticity
fix/991-comment-url-scheme-normalise
feat/push-guard-null-case-verification
mos-comms-live
docs/heartbeat-framework-layering-ms-lead
feat/869-c4-version-coupling
feat/869-c2-install-ordering-guard
feat/869-c5-doctor-activation-check
feat/per-agent-gitea-identity
fix/875-belongs-case-insensitive-slug
fix/ci-queue-wait-404-branch-absent
feat/869-c1-activation-probe
feat/869-c3-broker-supervisor
fix/865-tea-cli-comment-invocation
feat/glpi-skills
fix/860-deflake-mutator-lease-gate
fix/850-detect-platform-port-normalization
fix/856-worktree-deps-preflight
fix/835-pr-review-approve-reject-comment-flag
fix/848-truthful-evidence
fix/812-pr-review-comment
fix/849-recovery-runtime-fixture-race
docs/758-ledger-m5-001-sync
feat/834-tc-server-side-doc
feat/833-constrained-recovery-command
feat/827-gate0-probe
governance/gate0-probe3-amendment
fix/795-codex-pr-diff
fix/795-ci-base-jq
fix/795-ci-base-git
feat/791-pr3-fleet-regen
feat/791-pr2-snapshot-restore
fix/807-glpi-206
fix/808-agent-send-false-sender
feat/791-upgrade-config-protection
feat/790-mosaic-yolo-claudex-pr2
feat/790-mosaic-yolo-claudex
feat/758-v1-v2-migrator
fix/766-exact-fleet-comms
test/758-reconciler-lifecycle-gates
docs/771-kbn101-db-role-split
test/758-example-profile-dispositions
feat/758-shared-role-resolution
feat/mos-logical-identity-fencing
feat/769-kbn100-unified-schema
docs/753-kbn010-threat-gate
feat/758-roster-v2-compiler
feat/756-official-discord-plugin
docs/758-fleet-config-management
fix/mos-option2-qualification-format
docs/issue-758-m0
docs/mos-option2-qualification
mos-comms
feat/tess-interaction-agent
fix/tess-docs-format
draft/mosaic-platform-prd
fix/installer-provider-gate-and-local-gateway-redis
release/mosaic-cli-0.0.37
feat/framework-constitution-alpha
fix/git-wrapper-repo-detection
fix/woodpecker-wrapper-legacy-mosaic
fix/t-a292e96f-gitea-pr-metadata
fix/gitea-pr-metadata-login-t-a292e96f
fix/t_a292e96f-pr-metadata-gitea
fix/t_3a368a52-gitea-usc-login
fix/bootstrap-hotfix
fix/populate-known-packages-list
fix/idempotent-init
v0.0.39-alpha
mosaic-v0.0.31
fed-v0.2.0-m2
fed-v0.1.0-m1
mosaic-v0.0.29
mosaic-v0.0.28
mosaic-v0.0.27
mosaic-v0.0.26
mosaic-v0.0.25
mosaic-v0.0.24
v0.2.0
v0.1.0
v0.0.8
v0.0.7
v0.0.6
v0.0.5
v0.0.4
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mosaicstack/stack#1081
Reference in New Issue
Block a user
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.
Summary
tools/git/issue-close.shcallstea issue comment, which is not a subcommand oftea. On any host where a tea login is configured — the normal, correctly-configured case — the closing comment silently fails and the issue is closed anyway. The audit trail for why an issue was closed is lost, with no error surfaced.The same file already defines a working
gitea_issue_comment_api()helper, but it is only reached on the no-login fallback path.Evidence
Measured against
main@80a45b1e1c3b65999bd48c5b0f41f4b1cb702ff9:issue-close.sh:94(live code, comments stripped — 1 live call site):Two independent defects:
tea issue commentcannot succeed — the subcommand does not exist.||guards on it), so the script proceeds totea issue closeregardless.tea issue closeis valid, so the issue closes and the comment does not post.The no-login branch calls
gitea_issue_comment_api— which works — but it is also unchecked (:100), so it carries defect 2 on its own.Impact
This sits on the completion gate (linked issue closed). The closure outcome is unaffected; what is lost is the record of why, silently. This is the silent-failure class: an operation reports success while doing nothing.
Suggested fix
Route the comment through the existing
gitea_issue_comment_api()on both branches (it is login-independent and already proven), and fail closed — do not close the issue if the comment could not be posted:Alternatively keep
teaand correct it to the top-leveltea comment, but the API helper avoids depending on tea's subcommand surface and already exists in-file.Acceptance
Provenance note
This defect was independently fixed on a homelab host in July; that host-local edit routes both branches through the API helper with a fail-closed guard. The fix is being contributed upstream rather than left as undeclared host divergence.
No closing keywords intended; none used.
⛔ Correction to this issue's severity claim — from the author
I wrote that the issue closes anyway and the record of why is silently lost. That is wrong.
issue-close.shcarriesset -eat line 5, so the failingtea issue commentaborts the script. Measured againstmainunder a mockedtea:So there is no silent failure and no fail-open.
set -ealready fails closed, by accident rather than by design, and the "issue closes without its comment" scenario I described does not occur.What the defect actually is
issue-close.sh -c <comment>cannot succeed at all on any host where a tea login resolves.tea issue commentis not a subcommand, so the command aborts every time. The close path is fine; the commented close is simply broken.That is still a real bug — the documented way to close an issue with a note does not work — but it is loud, not silent, and it is a usability/availability defect rather than an audit-integrity one. I over-stated the severity and the mechanism.
What this changes about the fix
The change in #1085 is still correct and still needed, for narrower reasons:
tea comment(top-level) is the valid subcommand — this is the actual repair|| { ...; exit 1; }guard is still worth having: relying onset -efor a fail-closed property means the property silently disappears if anyone adds a|| true, wraps the call in a conditional, or runs the function in a context whereset -edoes not apply. A safety property that holds by accident is not a control.How I found it
The regression test I wrote for this went red on the unfixed script for the wrong reason — it fired on "wrong subcommand" rather than on "closed after the comment failed", which told me the close was never reached. Chasing that discrepancy produced the
set -efinding.The test that was supposed to prove the fix instead disproved the bug report. Recording that, because it is the argument for red-first testing better than anything I could assert.
No closing keywords intended; none used.