Repository navigation
fix(OMN-13141): runtime executor skips event_model import for operation_match entries - #1982
Conversation
…on_match entries
_run_event_driven unconditionally imported entry.event_model_module for every
resolved routing entry. operation_match entries declare no event_model, so
event_model_module is empty and importlib.import_module("") raised
ValueError: Empty module name — not caught by the (ImportError, AttributeError)
clause, swallowed by the outer except in run_async -> result FAILED. The node
never booted e2e (e.g. node_integration_sweep_orchestrator).
Gate the import block on a non-empty event_model_module: operation_match routes
by the operation field and forwards the raw decoded payload (input_model_cls=None);
only payload_type_match resolves a typed event model. Mirrors the strategy-aware
validator half (OMN-13137 / #1973), which is left untouched.
Adds tests/unit/runtime/test_run_event_driven_operation_match.py — a CI boot gate
that runs an operation_match contract through RuntimeLocal.run_async() and asserts
no empty-module ValueError, plus a payload_type_match regression guard.
|
Warning Review limit reached
More reviews will be available in 3 hours, 25 minutes, and 24 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
OMN-13141 — runtime executor skips event_model import for operation_match entries
Executor companion to OMN-13137 (#1973, merged on
dev), which fixed only the validator half. This PR fixes the disjoint executor half.Problem
RuntimeLocal._run_event_driven(src/omnibase_infra/runtime/runtime_local.py) unconditionally calledimportlib.import_module(entry.event_model_module)+getattr(...)for every resolved routing entry. Theexceptclause caught only(ImportError, AttributeError).For
operation_matchrouting entries (e.g.node_integration_sweep_orchestrator), handler entries carry noevent_model, so_resolve_routing_entriesyieldsevent_model_module="". Thenimportlib.import_module("")raisedValueError: Empty module nameatruntime_local.py:816— not caught by the(ImportError, AttributeError)clause, swallowed by the outerexcept Exceptioninrun_async→ workflow result FAILED. The node never booted end-to-end.OMN-13137 fixed only
_validate_routing(the static validation half); its test only validated the routing block, never booted throughrun_async(), so this path was uncovered.Fix
Gate the
importlib.import_module/getattrblock on a non-emptyevent_model_module:operation_matchentries route by theoperationfield and declare no payload model → skip the import, wire the adapter withinput_model_cls=None, and forward the raw decoded payload dict.payload_type_matchentries still resolve their typed event model (unchanged).LocalRuntimeBusAdapternow acceptsinput_model_cls: type[BaseModel] | None; onNoneit forwards the raw decoded dict to the handler. No silent broadening of theexcept— the skip is gated explicitly on the empty-module condition._validate_routingis left untouched (OMN-13137 owns it).CI boot gate
tests/unit/runtime/test_run_event_driven_operation_match.pyboots anoperation_matchcontract (empty event_model) throughRuntimeLocal.run_async()and asserts:ValueError: Empty module name/ result != FAILED-from-import (the bug);importlib.import_module("")is never called during operation_match wiring;payload_type_matchstill imports its event model (regression guard — a bad event_model module still FAILS).This test runs in the standard CI unit job (
@pytest.mark.unit, no infra markers), so it is wired as a pre-merge gate.Verification (local, in worktree)
uv run ruff format src/ tests/ && uv run ruff check --fix src/ tests/— cleanuv run mypy src/omnibase_infra/runtime/runtime_local.py src/omnibase_infra/runtime/runtime_local_adapter.py --strict— Success, no issuesuv run pytest tests/unit/runtime/ -q— 4886 passed, 5 skipped (pre-existing)origin/dev(bug reproduced at L816), 3 pass with the fixpre-commit runon changed files — all hooks pass (incl. union budget gate)dod_evidence
Per
contracts/OMN-13141.yaml(this PR):dod-boot-e2e:uv run pytest tests/unit/runtime/test_run_event_driven_operation_match.py -qdod-runtime-suite:uv run pytest tests/unit/runtime/ -qdod-deploy: internal runtime-executor correctness fix; no new topics/schema/container changes; runtime restart picks it up.OCC pairing
Paired OCC receipt PR: OmniNode-ai/onex_change_control#2620 (contract
contracts/OMN-13141.yaml+ PASS receipts underdrift/dod_receipts/OMN-13141/; verifierreceipt-gate-local≠ runner).Receipt Gate / DoD Gate evidence for OMN-13141:
Evidence-Source: OCC#2620
Evidence-Ticket: OMN-13141
(OCC#2620 carries
contracts/OMN-13141.yaml+ PASS receipts underdrift/dod_receipts/OMN-13141/; infra PR head is6d9402bbe43dc3379f4a2e72de35a60c5f0d7262.)Closes OMN-13141. Parent: OMN-13119 (delegation chain drift). Disjoint from #1973 / OMN-13137 (Done) — touches only
_run_event_driven, never_validate_routing.Receipt re-validated against OCC#2620 head 8fc03029e (contract_sha256 added).