Skip to content

Commit faf5129

Browse files
committed
fix(integrations): raise actionable error on malformed EXTRA_ARGS quoting
Wrap `shlex.split` in `_apply_extra_args_env_var` so an unmatched quote in `SPECIFY_INTEGRATION_<KEY>_EXTRA_ARGS` surfaces a clear `ValueError` naming the offending env var and showing the invalid value, instead of crashing workflow dispatch with a bare shlex traceback. Adds a new test locking the actionable error path. Addresses Copilot review feedback on #2596.
1 parent c39d1db commit faf5129

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

src/specify_cli/integrations/base.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,18 @@ def _apply_extra_args_env_var(self, args: list[str]) -> None:
164164
f"SPECIFY_INTEGRATION_{self.key.upper().replace('-', '_')}_EXTRA_ARGS"
165165
)
166166
extra = os.environ.get(env_name, "").strip()
167-
if extra:
168-
args.extend(shlex.split(extra))
167+
if not extra:
168+
return
169+
try:
170+
tokens = shlex.split(extra)
171+
except ValueError as exc:
172+
raise ValueError(
173+
f"{env_name} is not parseable as a POSIX-quoted command line "
174+
f"(value: {extra!r}). shlex reported: {exc}. "
175+
f"Use single or double quotes to group multi-word values, e.g. "
176+
f'{env_name}=\'--flag "value with spaces"\'.'
177+
) from exc
178+
args.extend(tokens)
169179

170180
def build_command_invocation(self, command_name: str, args: str = "") -> str:
171181
"""Build the native slash-command invocation for a Spec Kit command.

tests/integrations/test_extra_args.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,21 @@ def test_env_var_multi_token_parsed_via_shlex(monkeypatch):
135135
]
136136

137137

138+
def test_malformed_quoting_raises_actionable_value_error(monkeypatch):
139+
"""An unmatched quote in the env-var value must surface a clear
140+
error naming the offending env var and showing the invalid value,
141+
rather than crashing workflow dispatch with a bare shlex traceback."""
142+
monkeypatch.setenv(
143+
"SPECIFY_INTEGRATION_CLAUDE_EXTRA_ARGS",
144+
'--flag "unterminated',
145+
)
146+
with pytest.raises(ValueError) as excinfo:
147+
_ClaudeStub().build_exec_args("p")
148+
msg = str(excinfo.value)
149+
assert "SPECIFY_INTEGRATION_CLAUDE_EXTRA_ARGS" in msg
150+
assert "--flag \"unterminated" in msg
151+
152+
138153
def test_env_var_empty_or_whitespace_is_noop(monkeypatch):
139154
"""An env var set to '' or ' ' is treated as unset."""
140155
monkeypatch.setenv("SPECIFY_INTEGRATION_CLAUDE_EXTRA_ARGS", " ")

0 commit comments

Comments
 (0)