Baseline
Reproduced from v1.3.1 at 5a306f8956cb1eeae69f9709de0e4d61b44e11e7.
Reproduction
Create agents-cli-manifest.yaml with each of these shapes and run a command that reads project config, for example agents-cli info --json:
Scalar/list variants of create_params fail similarly.
Actual behavior
The loader uses yaml.safe_load(f) or {}, so empty and null manifests silently become defaults. Scalar and list top-level values, or non-mapping create_params, later fail with Python attribute/type errors and expose a traceback instead of one CLI error.
Expected behavior
An existing manifest must have a mapping at the top level, and create_params must also be a mapping when present. Empty, null, scalar, list, and invalid create_params shapes should all exit nonzero with one understandable Click error and no traceback. Valid manifests must keep their current behavior.
Minimal fix
Validate both YAML boundaries with collections.abc.Mapping immediately after loading, then raise one click.ClickException before constructing ProjectConfig. Do not add a schema framework or dependency.
Reference implementation: benagentai93-dot@c6bb414
Test evidence
Runnable CLI regressions cover empty, null, scalar, list, and three invalid create_params shapes. Every invalid case exits 1 with a single error and no traceback; a valid manifest remains JSON-parseable with the expected fields.
Fork verification:
- focused Batch 3 suite: 15 passed
- full root suite: 55 passed
ruff check src tests: passed
ty check src: passed
uv build: passed
- installed-wheel
agents-cli --version: 1.3.1 on Python 3.11 and 3.13
All focused regressions use mocks; no real npx, network, or server command was run.
Baseline
Reproduced from v1.3.1 at
5a306f8956cb1eeae69f9709de0e4d61b44e11e7.Reproduction
Create
agents-cli-manifest.yamlwith each of these shapes and run a command that reads project config, for exampleagents-cli info --json:# empty filenullscalar- itemScalar/list variants of
create_paramsfail similarly.Actual behavior
The loader uses
yaml.safe_load(f) or {}, so empty andnullmanifests silently become defaults. Scalar and list top-level values, or non-mappingcreate_params, later fail with Python attribute/type errors and expose a traceback instead of one CLI error.Expected behavior
An existing manifest must have a mapping at the top level, and
create_paramsmust also be a mapping when present. Empty,null, scalar, list, and invalidcreate_paramsshapes should all exit nonzero with one understandable Click error and no traceback. Valid manifests must keep their current behavior.Minimal fix
Validate both YAML boundaries with
collections.abc.Mappingimmediately after loading, then raise oneclick.ClickExceptionbefore constructingProjectConfig. Do not add a schema framework or dependency.Reference implementation: benagentai93-dot@c6bb414
Test evidence
Runnable CLI regressions cover empty,
null, scalar, list, and three invalidcreate_paramsshapes. Every invalid case exits 1 with a single error and no traceback; a valid manifest remains JSON-parseable with the expected fields.Fork verification:
ruff check src tests: passedty check src: passeduv build: passedagents-cli --version: 1.3.1 on Python 3.11 and 3.13All focused regressions use mocks; no real
npx, network, or server command was run.