fix: reject victorialogs raw rows query missing start/end args#87
fix: reject victorialogs raw rows query missing start/end args#87ysyneu wants to merge 2 commits into
Conversation
monit-query rows dispatched --ds-type victorialogs with --args victorialogs.type=raw straight to the backend without checking for victorialogs.start/victorialogs.end. The backend silently returns null (HTTP 200, exit 0) instead of an error, which caused an agent session to retry the same broken call ~10+ times before finding the doc that explains the raw-mode contract. Validate this known-bad combination client-side before dispatch, mirroring the existing required-flags check in the same RunE.
The referenced skills/flashduty/reference/monit-query.md doesn't document victorialogs.start/end and its Gotchas section says the opposite for rows in general, so the pointer misled readers. The error text alone already states the fix.
|
Closing after tracing the contract ownership end to end. The public OpenAPI and the go-flashduty version already pinned by feat/ai-sre allow VictoriaLogs raw queries to provide either victorialogs.start + victorialogs.end or victorialogs.timespan.value + victorialogs.timespan.unit. This PR only accepts the first form, so it incorrectly rejects a valid SDK/OpenAPI request and duplicates API semantics in the CLI layer. The underlying null/HTTP-200 failure is addressed at the service boundary in monit-webapi: 31f8f37 validates both time-range forms and maps Edge errors to real HTTP error statuses; aa22cb8 extends the shared query-rows validator. The CLI should keep using go-flashduty as its contract boundary instead of maintaining a narrower copy here. Keeping the branch for traceability; no code from this PR should merge. |
Root cause
newMonitQueryRowsCmd's RunE (internal/cli/monit_query.go) only validated that--ds-type,--ds-name,--exprwere non-empty and that--argsentries parsed asKEY=VALUE. It never inspected the values of--args, sofduty monit-query rows --ds-type victorialogs --args victorialogs.type=rawwith novictorialogs.start/victorialogs.endwas dispatched straight to the backend. VictoriaLogs raw mode requires those two args, but the backend silently returnsnull(HTTP 200, exit 0) instead of an error when they're missing, and the CLI just echoed it through.Evidence
Audit run
audit-20260715T031903Z-auto, sessionsess_5JSe2TeGpyKMTQAW8pGAxS: the agent hit this exact combination ~10+ times (transcript steps 42-83, repeatednull/[]results) before it happened to find the relevant reference doc.Fix
Client-side guard in
newMonitQueryRowsCmd's RunE, right after--argsparsing and before dispatch: if--ds-type victorialogsand--args victorialogs.type=raware set butvictorialogs.startorvictorialogs.endis missing, return a clear error instead of calling the backend. Mirrors the existing required-flags check in the same function. Scope is intentionally narrow — only this one known-bad combination is validated, matching what the transcript evidence shows; other ds-type/arg contracts (e.g. loki) are left untouched per Occam's razor.Revision (review blocker fix)
The initial error message pointed readers to
skills/flashduty/reference/monit-query.mdfor the start/end requirement. Review caught that this doc doesn't documentvictorialogs.type/.start/.endat all, and its Gotchas section states the opposite forrowsin general ("no time flags — embed the range in--expr"), which would confuse rather than help. There is noreference/victorialogs.mdfile anywhere in this repo either. Rather than bolt on doc content to reconcile a general-vs-exception rule (out of scope for this narrow client-side fix), the doc pointer was dropped from the error string — the error text alone already states exactly what's required (--args victorialogs.start=<unix> --args victorialogs.end=<unix>), so no external reference is needed to resolve it.RED → GREEN
RED (before the fix):
(stub.requests == 1 confirms the call was dispatched to the backend before the fix, matching the silent-passthrough root cause.)
GREEN (after adding the RunE guard, and after dropping the doc pointer in the revision):
Final verification (fresh, post-revision)
go test ./internal/cli/... -run TestMonitQueryRows -v— all PASS (Flags, HappyPath, RequiredFlags x3, InvalidArgs, VictorialogsRawRequiresTimeRange)go build ./...— OKgo vet ./...— OKgofmt -l internal/cli/monit_query.go— no output (clean)git diff --statagainst the prior commit — onlyinternal/cli/monit_query.go, 1 line changed (removed the doc-pointer suffix from the error string); no other files touched0dcc519):lint,build (ubuntu-latest),build (macos-latest),build (windows-latest),Analyze (go),Analyze (actions),CodeQL— all PASS. PR isMERGEABLE/CLEANagainstfeat/ai-sre.Test plan
monit-query rows/diagnosetest suitego build/go vet/gofmtclean