Skip to content

flows: migrate-legacy-workflow.py raises AttributeError on scalar step instead of REFUSED #270

Description

@kjgbot

Summary

ops/schema-migration/migrate-legacy-workflow.py:120 calls s.get('type') without validating that each step is a mapping. A valid YAML document with steps: [invalid-scalar] raises AttributeError: 'str' object has no attribute 'get' and exits 1, instead of returning the documented REFUSED diagnostic. The refusal-boundary contract the script advertises is not enforced for this case.

Surfaced during the 2026-09-10 launch-prep PR sweep; reproduced at head bcafd4218c7011cc3ec4214d1c14703547a59fac in an isolated PyYAML 6.0.3 venv against a byte-for-byte source extract. The relevant flows PR is #238, whose commentary called this out but did not fix the guard.

Repro

schema-migration-input.yaml:

version: '1.0'
name: test
workflows:
  - name: test
    steps:
      - invalid-scalar
python3 ops/schema-migration/migrate-legacy-workflow.py schema-migration-input.yaml

Actual:

Traceback (most recent call last):
  ...
  File "ops/schema-migration/migrate-legacy-workflow.py", line 120, in ...
    step_type = s.get('type')
AttributeError: 'str' object has no attribute 'get'

Expected

The script emits a REFUSED diagnostic naming the malformed step and its shape, exit 1 with the diagnostic on stderr — same contract the rest of migrate uses for malformed inputs.

Suggested direction

At line 120, validate isinstance(s, dict) before .get. On failure, emit REFUSED [malformed_step] step at index N is not a mapping (got <type>). Add a regression test covering scalar-step and non-dict-step inputs to the migrate test suite.

Acceptance criteria

  • python3 ops/schema-migration/migrate-legacy-workflow.py <yaml-with-scalar-step> exits 1 with a REFUSED diagnostic instead of a Python traceback.
  • Regression test asserts the exact diagnostic shape for a scalar step, a null step, and a step that is a list.

Context

Filed from the sweep report at commit 64de443 on branch sweep/v2-launch-prep-0910. See PR-SWEEP-REPORT-0910.md §#238 and ops/runtime-evidence/pr-sweep-0910.txt for the exact traceback.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions