Skip to content

Commit 017e84d

Browse files
doquanghuyclaude
andcommitted
fix(workflows): coerce gate prompt message to str before rendering
The multi-line render loop split the message on newlines, which assumes a str. A non-string message (e.g. a YAML numeric literal) previously rendered fine through the old f-string and would now raise on .split. Coerce with str() to preserve that tolerance, and add a regression test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent bf37635 commit 017e84d

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

src/specify_cli/workflows/steps/gate/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ def _prompt(message: str, options: list[str]) -> str:
106106
been folded in); each line is rendered inside the gate box.
107107
"""
108108
print("\n ┌─ Gate ─────────────────────────────────────")
109-
for line in message.split("\n"):
109+
# ``str(...)`` so a non-string message (e.g. a YAML numeric literal)
110+
# renders rather than raising on ``.split``.
111+
for line in str(message).split("\n"):
110112
print(f" │ {line}" if line else " │")
111113
print(" │")
112114
for i, opt in enumerate(options, 1):

tests/test_workflows.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,22 @@ def test_read_show_file_invalid_path_does_not_raise(self):
922922
assert len(rendered) == 1
923923
assert rendered[0].startswith("(could not read file:")
924924

925+
def test_interactive_non_string_message_renders(self, monkeypatch, capsys):
926+
from specify_cli.workflows.steps.gate import GateStep
927+
from specify_cli.workflows.base import StepContext, StepStatus
928+
929+
# A YAML numeric literal reaches the prompt as a non-string; it must
930+
# render rather than crash on the multi-line split.
931+
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
932+
monkeypatch.setattr("builtins.input", lambda _prompt="": "1")
933+
934+
step = GateStep()
935+
config = {"id": "review", "message": 123, "options": ["approve", "reject"]}
936+
result = step.execute(config, StepContext())
937+
out = capsys.readouterr().out
938+
assert "123" in out
939+
assert result.status == StepStatus.COMPLETED
940+
925941
def test_templated_show_file_resolving_to_non_string_is_coerced(self):
926942
from specify_cli.workflows.steps.gate import GateStep
927943
from specify_cli.workflows.base import StepContext, StepStatus

0 commit comments

Comments
 (0)