diff --git a/lib/cli/src/crewai_cli/run_declarative_flow.py b/lib/cli/src/crewai_cli/run_declarative_flow.py index e3f3abad1..d3c58c1cf 100644 --- a/lib/cli/src/crewai_cli/run_declarative_flow.py +++ b/lib/cli/src/crewai_cli/run_declarative_flow.py @@ -89,10 +89,11 @@ def _resolve_flow_inputs(flow: Any, provided: dict[str, Any]) -> dict[str, Any]: defaults = _flow_state_defaults(flow) # Unknown keys are almost always typos — warn and drop them (they'd fail - # structured-state validation at kickoff anyway). + # structured-state validation at kickoff anyway). ``id`` is a reserved + # kickoff key (persistence restore), so let it through untouched. collected: dict[str, Any] = {} for key, value in provided.items(): - if key in properties: + if key in properties or key == "id": collected[key] = value continue suggestion = _closest_key(key, properties) @@ -112,7 +113,9 @@ def _resolve_flow_inputs(flow: Any, provided: dict[str, Any]) -> dict[str, Any]: for name in missing: description = (properties.get(name) or {}).get("description") suffix = f" — {description}" if description else "" - click.secho(f" Missing required input '{name}'{suffix}", fg="red", err=True) + click.secho( + f" Missing required input '{name}'{suffix}", fg="red", err=True + ) raise SystemExit(1) _validate_flow_inputs(state_model, {**defaults, **collected}) diff --git a/lib/cli/tests/test_run_declarative_flow.py b/lib/cli/tests/test_run_declarative_flow.py index 396578cd6..3364135a1 100644 --- a/lib/cli/tests/test_run_declarative_flow.py +++ b/lib/cli/tests/test_run_declarative_flow.py @@ -335,3 +335,19 @@ def test_validates_input_types_before_kickoff( run_declarative_flow_module.run_declarative_flow(str(path), '{"count":"nope"}') assert "Invalid input 'count'" in capsys.readouterr().err + + +def test_reserved_id_input_is_forwarded_not_dropped( + tmp_path: Path, capsys: pytest.CaptureFixture[str] +) -> None: + # `id` is a reserved kickoff key (persistence restore); it must pass through + # instead of being flagged as an unknown key and dropped. + path = _write(tmp_path, REQUIRED_FLOW_YAML) + + run_declarative_flow_module.run_declarative_flow( + str(path), '{"id":"run-123","prospect_email":"a@b.com"}' + ) + + captured = capsys.readouterr() + assert captured.out == "a@b.com\n" + assert "Ignoring unknown input 'id'" not in captured.err