mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-07-22 15:25:09 +00:00
fix(cli): don't block persistence-restore resume on schema validation
Cursor (High): `crewai run --inputs '{"id":"…"}'` is a persistence resume —
kickoff hydrates full state from storage, so schema-required fields may come
from the restored state rather than --inputs. The new required-field
prompt/validation was erroring/prompting before kickoff, breaking resume. When
`id` is present in --inputs, forward the inputs unchanged and skip the
prompt/validation. Test: test_id_only_input_skips_required_validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RBYGqJHC2TMC6fonFziuuh
This commit is contained in:
@@ -80,6 +80,13 @@ def _resolve_flow_inputs(flow: Any, provided: dict[str, Any]) -> dict[str, Any]:
|
||||
# dict / unschematized state — nothing to derive; pass inputs through.
|
||||
return dict(provided)
|
||||
|
||||
# ``id`` signals a persistence restore: kickoff hydrates the full state from
|
||||
# storage, so required fields may come from the restored state rather than
|
||||
# --inputs. Forward the inputs unchanged instead of prompting/erroring for
|
||||
# fields the resume will supply.
|
||||
if "id" in provided:
|
||||
return dict(provided)
|
||||
|
||||
properties = {
|
||||
name: spec
|
||||
for name, spec in (schema.get("properties") or {}).items()
|
||||
@@ -89,11 +96,10 @@ 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). ``id`` is a reserved
|
||||
# kickoff key (persistence restore), so let it through untouched.
|
||||
# structured-state validation at kickoff anyway).
|
||||
collected: dict[str, Any] = {}
|
||||
for key, value in provided.items():
|
||||
if key in properties or key == "id":
|
||||
if key in properties:
|
||||
collected[key] = value
|
||||
continue
|
||||
suggestion = _closest_key(key, properties)
|
||||
|
||||
@@ -351,3 +351,14 @@ def test_reserved_id_input_is_forwarded_not_dropped(
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "a@b.com\n"
|
||||
assert "Ignoring unknown input 'id'" not in captured.err
|
||||
|
||||
|
||||
def test_id_only_input_skips_required_validation(tmp_path: Path) -> None:
|
||||
# Resume via `crewai run --inputs '{"id":"..."}'` must not be blocked by the
|
||||
# required-field check: kickoff hydrates required state from persistence.
|
||||
path = _write(tmp_path, REQUIRED_FLOW_YAML)
|
||||
flow = run_declarative_flow_module.load_declarative_flow(str(path))
|
||||
|
||||
resolved = run_declarative_flow_module._resolve_flow_inputs(flow, {"id": "run-123"})
|
||||
|
||||
assert resolved == {"id": "run-123"}
|
||||
|
||||
Reference in New Issue
Block a user