--- id: "bug-1744" status: "fixed" status_updated: "2026-09-27" status_note: "b970ab75: apiserver checks rusage[] syntax at submit via libxce's grammar; select/order names still scheduler-side only" component: "lib" severity: "unknown" timestamp: "2026-09-01T05:45:00Z" last_seen: "2026-09-19T09:00:00Z" occurrences: 1 files: ["src/frontend/xcecli/cmd/jobs/submit.go (resReq flag", "no value validation", "just passed through: jobReq.Resreq = js.resReq)", "src/frontend/apiserver/controllers/jobs.go:1602-1606 (only length-checks Resreq", "no syntax/grammar validation)", "src/lib/resreq.c (parse_resreq/parse_rusage -- the real PEG-generated grammar parser)", "src/lib/rusage.peg (rusage_param grammar", "mem value must match `number <- [0-9]+('.'[0-9]*)?`", "so \"100000000a0\" is a genuine grammar violation)", "src/scheduler/src/core_events.c:236-245 (parse_resreq call site inside core_build_job()) and :751-760 (JOBS_PUSH caller: on core_build_job()==NULL", "WARNs server-side and `continue`s -- job silently dropped", "never added to core->jobs)"] tags: ["apiserver", "xcecli", "job-submission", "resreq", "rusage", "validation-gap", "silent-failure", "phantom-pend", "new", "found-static-analysis", "needs-live-repro", "related-to-bug-1740", "not-yet-fixed", "deprioritized", "deferred"] related: [] fix_commits: ["b970ab75"] legacy: true gitea_issue: 47 gitea_synced_status: "fixed" gitea_synced_hash: "2de27f57fdcf" --- # bug-1744: Gitea issue #47 (rusage是否做了?): `xcecli jobs submit -R "rusage[mem=100000000a0]"` -- a malformed… ## Description Gitea issue #47 (rusage是否做了?): `xcecli jobs submit -R "rusage[mem=100000000a0]"` -- a malformed resreq string (trailing non-numeric "a0" on the mem value) -- is silently ACCEPTED and returns a normal 'Job <...> is submitted' success message. Reporter's original comment: '乱写也可以提交' (garbage input can be submitted too). Maintainer (rshen) already commented on the issue: this is a front-end (apiserver+cli) validation gap by design intent. ## Environment _Not recorded (migrated from buglog.json)._ ## Reproduction _Not recorded (migrated from buglog.json)._ ## Root cause The ONLY resreq validation in the entire submission path is a length check (apiserver/controllers/jobs.go:1602-1606, `len(req.Resreq) > 4094`) -- there is no syntax/grammar validation anywhere client-side or in the apiserver before a job is accepted and persisted. The REAL validator, a PEG-generated grammar parser (parse_resreq()/parse_rusage(), src/lib/resreq.c, built from src/lib/rusage.peg + xce_resreq.peg via meson custom_target), exists but is only ever invoked deep inside the C scheduler at core_build_job() time (core_events.c:236), i.e. asynchronously, well AFTER the apiserver has already accepted the job, returned a submission-success response to the client, and persisted it. When parse_resreq() fails on malformed syntax (confirmed via rusage.peg's `number` rule, `[0-9]+('.'[0-9]*)?` -- "100000000a0" cannot match this and leaves "a0" unconsumed, a genuine PEG parse failure), core_build_job() logs an ERROR and returns NULL (core_events.c:238-245); its caller in the XCE_CORE_EVENT_JOBS_PUSH handler (core_events.c:756-760) only logs a server-side WARN and `continue`s to the next job in the batch -- the malformed job is silently dropped from the scheduler's core->jobs registry entirely. Net effect is worse than 'garbage accepted': the job is accepted, shows the user a success message, is almost certainly persisted and shown as PEND via `jobs list` (this session did not confirm the exact persisted/listed state live), and then sits PEND FOREVER with zero indication to the user that anything is wrong -- the only trace is a server-side log line the user never sees. This is architecturally the same class of gap as bug-1740 (a real, working validator/reconciler exists but is wired into the wrong -- or in this case, too-late -- point in the pipeline) and matches the maintainer's own comment that front-end validation is the intended design, not yet implemented. ## Fix NOT YET FIXED -- investigated and design-confirmed this session; DEPRIORITIZED, deferred to later (explicit user decision, not urgent). Confirmed fix approach: validate resreq synchronously in the apiserver's submit handler (controllers/jobs.go:1602, alongside the existing length check), reusing libxce's existing PEG parser rather than reimplementing the grammar in Go. Specifically parse_rusage() (src/lib/resreq.c:154, declared resreq.h:301 -- `int parse_rusage(xlist_t*, char*, char**)`) needs NO resmgr/resource-manager context, unlike the fuller parse_resreq()/parse_select() (resreq.h:303,305 -- both take a `var resmgr` to validate resource NAMES in select[]/order[] clauses, which the apiserver doesn't currently construct) -- so a resreq-name-agnostic rusage[]-only syntax check is a small, low-risk CGo wrapper, not a larger resmgr-plumbing project. apiserver/backend already has the exact split pattern to follow: a `//go:build cgo` file with the real implementation (e.g. clib.go, which already #includes libxce headers and links -lxce) plus a `//go:build !cgo` stub (stub.go, returns an errNoCGO-style error) for the CGO-disabled test path. Full parse_resreq()/resmgr-backed select[]/order[] validation is explicitly out of scope for now -- would be a separate, larger follow-up if wanted. SCOPE DECISION (2026-09-01): will be implemented as a direct bugfix when picked up, NOT a kiro spec -- small, contained blast radius (one new CGo wrapper + stub in apiserver/backend, one call site in controllers/jobs.go, matching the size/shape of the already-shipped bug-1742/bug-1743 fixes), no HA/persistence/RBAC involvement, and no open design questions left (exact function, signature, and existing cgo/stub pattern to follow are already nailed down). Only the FULLER resmgr-backed select[]/order[] validation (out of scope here) would warrant at least a /kiro-spec-quick, since it needs new apiserver-side state (a resmgr context kept in sync with resource definitions) -- not needed for this rusage-only fix. ## Verification _Not recorded (migrated from buglog.json)._ ## References - Gitea: #47