Skip to content

discover where: CEL context conversion overflows on uint64 values in unrelated fields, failing the whole query #65

Description

@soupat

Summary

discover(..., where=...) (PR #64) fails for an entire device type when any integer in a device's stored record lies outside int64, even if the predicate never touches that field. The registry answers -32000 overflow and the agent tools surface connection_error: Registry error (-32000): overflow, so the state query is unusable for that fleet.

Repro

A device whose status carries a field contract with a uint64 bound, e.g. an OpenConfig counter:

"status": {"benchmark_snapshot": {"readings": {"age": {"value": 30}},
           "field_contracts": {"age": {"schema": {"maximum": 18446744073709551615}}}}}

discover("device(model_id:oc:lldp_neighbor)", where="status.benchmark_snapshot.readings.age.value == 30")
Registry error (-32000): overflow

Cause: WherePredicate.evaluate hands the whole {identity, labels, status} context to cel-python, which converts every value to a CEL type up front and raises ValueError("overflow") for integers beyond int64. registry.list_devices only catches PredicateEvalError, so the ValueError escapes and aborts the whole listing instead of marking that device a non-match. The same conversion runs in the edge-side broadcast where.

Observed in an LLM-agent benchmark run (Codex Astra, 2026-09-15) against the fixture registry that mirrors this code path: every where query over oc:* models failed; 34 devices in scope, all raising. Our fixture now coerces out-of-range integers to floats before evaluation as a workaround.

Proposal

  • In predicate.py, convert the context defensively before evaluation: integers outside int64 become floats (or strings), so an unrelated field cannot break a predicate on another field. Document that comparisons against such values are float comparisons.
  • In registry.list_devices (and the broadcast self-election path), treat any exception raised while evaluating one device as a non-match for that device, matching the documented "does not match" rule, rather than failing the whole call.
  • Add a regression with a uint64 maximum in a field contract and a predicate on a sibling field.

Relates to #63 / #64.

Activity

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions