Description
validate_workflow() and the workflow add local-install path assume every scalar in workflow.yml is a string. YAML parses unquoted values like 1.0 and 123 as float/int, so a small authoring mistake crashes the CLI with a raw traceback instead of a validation error.
Reproduction
Tested on current main (0.12.9.dev0).
1. Unquoted version — version: 1.0 instead of version: "1.0.0":
workflow:
id: probe
name: Probe
version: 1.0
File "src/specify_cli/workflows/engine.py", line 152, in validate_workflow
elif not re.match(r"^\d+\.\d+\.\d+$", definition.version):
TypeError: expected string or bytes-like object, got 'float'
2. Numeric workflow id — id: 123:
File "src/specify_cli/workflows/_commands.py", line 604, in _validate_and_install_local
if not definition.id or not definition.id.strip():
AttributeError: 'int' object has no attribute 'strip'
3. Numeric step id — steps: [{id: 123, type: shell, run: echo hi}]:
File "src/specify_cli/workflows/engine.py", line 263, in _validate_steps
if ":" in step_id:
TypeError: argument of type 'int' is not iterable
Related: schema_version: 1.0 (unquoted) doesn't crash but produces a confusing message: Unsupported schema_version 1.0. Expected '1.0'. — the float renders identically to the accepted string.
Expected
Clean validation errors from workflow validate/workflow add, e.g. Workflow version 1.0 must be a string — quote it in YAML (version: "1.0.0").
Root cause
validate_workflow() in src/specify_cli/workflows/engine.py regex-matches and iterates definition.id, definition.version and step id values without checking they are strings first. Same for the definition.id.strip() call in _validate_and_install_local. Since this is the shared validation path, the crash reaches workflow add, workflow validate and catalog installs alike.
I have a fix ready and will open a PR.
Description
validate_workflow()and theworkflow addlocal-install path assume every scalar inworkflow.ymlis a string. YAML parses unquoted values like1.0and123as float/int, so a small authoring mistake crashes the CLI with a raw traceback instead of a validation error.Reproduction
Tested on current main (0.12.9.dev0).
1. Unquoted version —
version: 1.0instead ofversion: "1.0.0":2. Numeric workflow id —
id: 123:3. Numeric step id —
steps: [{id: 123, type: shell, run: echo hi}]:Related:
schema_version: 1.0(unquoted) doesn't crash but produces a confusing message:Unsupported schema_version 1.0. Expected '1.0'.— the float renders identically to the accepted string.Expected
Clean validation errors from
workflow validate/workflow add, e.g.Workflow version 1.0 must be a string — quote it in YAML (version: "1.0.0").Root cause
validate_workflow()insrc/specify_cli/workflows/engine.pyregex-matches and iteratesdefinition.id,definition.versionand stepidvalues without checking they are strings first. Same for thedefinition.id.strip()call in_validate_and_install_local. Since this is the shared validation path, the crash reachesworkflow add,workflow validateand catalog installs alike.I have a fix ready and will open a PR.