--- id: "bug-1787" status: "fixed" status_updated: "2026-09-24" status_note: "" component: "scheduler" severity: "unknown" timestamp: "2026-09-07T09:45:00Z" last_seen: "2026-09-19T09:00:00Z" occurrences: 1 files: ["src/scheduler/src/plugins/limit.c (match_job_global_limit_", "match_job_host_limit_)"] tags: ["scheduler", "limit-plugin", "rtti", "pointer-indirection", "type-confusion", "gitea-46", "live-verified"] related: ["bug-1784", "bug-1785", "bug-1786", "bug-1788", "bug-1789"] legacy: true gitea_issue: 46 gitea_synced_status: "fixed" --- # bug-1787: Found immediately after bug-1786: match_job_global_limit_'s own key_find rc=-2 masking fixed, but… ## Description Found immediately after bug-1786: match_job_global_limit_'s own key_find rc=-2 masking fixed, but the FOLLOWING step -- instantiate_limit() -- now returned rc=-22/-EINVAL outright, still aborting the loop after the first limit. ## Environment _Not recorded (migrated from buglog.json)._ ## Reproduction _Not recorded (migrated from buglog.json)._ ## Root cause is_host_based_limit() and instantiate_limit() (src/lib/xcelimit.c) both take a plain `var resmgr` parameter -- core.h declares core.resmgr itself as a plain `var` (a handle, not var*), matching how every other manager consumer in this codebase (get_group(), is_in_group(), key_find() itself) takes its manager by value. All four call sites in limit.c (2 in match_job_global_limit_, 2 in the host-scoped sibling match_job_host_limit_) instead passed &(sched->core.resmgr) -- the ADDRESS of the field, one level of indirection too many. RTTI's key_find() dispatch received what amounts to a var* misinterpreted as a var (a meta_obj_t* pointing at raw, non-RTTI memory) and rejected it: silently inside is_host_based_limit() (whose own rc<=0 guard turns ANY key_find failure, including this type-confusion, into a uniform -ENOENT -- see bug-1786's note on why that specific defensive pattern isn't itself wrong), but fatally inside instantiate_limit(), whose own key_find() call on the SAME mistyped resmgr returned -EINVAL and (before this session's other fixes) propagated straight out. ## Fix FIXED (2026-09-07). Removed the erroneous & at all 4 call sites (2 in match_job_global_limit_, 2 in match_job_host_limit_): `is_host_based_limit(sched->core.resmgr, limit)` / `instantiate_limit(&vres, sched->core.resmgr, limit, ...)`. Confirmed via live diagnostic instrumentation (temporary, removed before landing) that instantiate_limit()'s own top-of-function NULL-argument dump showed every argument non-NULL yet still failing -- proving the -EINVAL came from RTTI's own internal type/handle validation inside key_find(), not the function's explicit guard clause, which directly confirmed the type-confusion theory before touching production code. Full scheduler suite: 76/77 (pre-existing bug-1762). LIVE-VERIFIED as part of the combined bug-1784/1785/1786/1788 trace. ## Verification _Not recorded (migrated from buglog.json)._ ## References - Related: bug-1784, bug-1785, bug-1786, bug-1788, bug-1789 - Gitea: #46