openclaw - 💡(How to fix) Fix [Bug]: Usage page agent filter broken since v2026.5.17 – sessions.usage API always scoped to "main" agent [5 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

After commit 6a12c6f79915 (v2026.5.17), the sessions.usage backend handler scopes session discovery by agentId, defaulting to "main" when no agentId is provided – but the Web UI frontend (ui/src/ui/controllers/usage.ts) never sends agentId in the API request, so non-main agent sessions are never returned and the client-side agent filter popover (added by renderFilterSelect("agent", ...)) only sees main sessions.

Root Cause

Before v2026.5.17, the sessions.usage endpoint returned sessions across all agents without agent-scoping, and the client-side agent filter could be used to narrow down results. After a regression fix, the agent filter should pass the selected agentId to the API so the backend returns the correct agent's sessions; the client-side query-based filter alone is insufficient because the backend already drops non-main sessions.

Fix Action

Fixed

Code Example

Root cause commit: 6a12c6f7991547c0bf82323392ca327f4de016a3
- Author: pgondhi987
- Message: fix(gateway): scope session data lookups by agent [AI] (#81386)
- PR: #81386
- Changelog entry (v2026.5.17): "Gateway/sessions: scope session data lookups by agent id so multi-agent gateway state cannot cross-leak session records across configured agents."
Backend handler (src/gateway/server-methods/usage.ts, lines added by this commit):
const requestedAgentId = normalizeOptionalString$1(p.agentId);
// ...
const effectiveAgentId = normalizeAgentId(
  requestedAgentId ?? specificKeyAgentId ?? resolveDefaultAgentId(config)
);
//                           ^^^^^^^^^^^^^^^^^^^^^^^^ defaults to "main"
const scopedStore = filterSessionStoreByAgent({
  config, store, agentId: effectiveAgentId
});
Frontend controller (ui/src/ui/controllers/usage.ts:88-107) – the sessions.usage call never includes agentId:
client.request("sessions.usage", {
  startDate,
  endDate,
  ...dateInterpretation,   // mode, utcOffset
  ...usageScopeParams,     // groupBy, includeHistorical
  limit: 1000,
  includeContextWeight: true,
  // ⚠️ missing: agentId
});
The agent filter UI in ui/src/ui/views/usage.ts (renderFilterSelect("agent", ...)) only adds agent:xxx query tokens for client-side filtering – it does not affect the API parameters. This worked before v2026.5.17 because the backend had no agent-scoping.
Swift protocol was updated in the same commit (apps/shared/OpenClawKit/.../GatewayModels.swift)SessionsUsageParams gained agentId – so the macOS native client can send the field, but the Web UI was missed.
Before this commit (9a204008ba0), usage.ts had NO requestedAgentId, filterSessionStoreByAgent, or agent-based scoping in discoverAllSessionsForUsage – all agents' sessions were returned.
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

After commit 6a12c6f79915 (v2026.5.17), the sessions.usage backend handler scopes session discovery by agentId, defaulting to "main" when no agentId is provided – but the Web UI frontend (ui/src/ui/controllers/usage.ts) never sends agentId in the API request, so non-main agent sessions are never returned and the client-side agent filter popover (added by renderFilterSelect("agent", ...)) only sees main sessions.

Steps to reproduce

  1. Configure OpenClaw with multiple agents (e.g., main and secondary) and generate usage across both.
  2. Open the Control UI Usage page (/usage) at v2026.5.22.
  3. Click the "agent" filter popover in the query bar – only main appears in the option list.
  4. Open browser DevTools Network tab, observe sessions.usage request payload – no agentId field is sent.
  5. The backend resolves requestedAgentId to undefined, then falls through to resolveDefaultAgentId(config) → "main".

Expected behavior

Before v2026.5.17, the sessions.usage endpoint returned sessions across all agents without agent-scoping, and the client-side agent filter could be used to narrow down results. After a regression fix, the agent filter should pass the selected agentId to the API so the backend returns the correct agent's sessions; the client-side query-based filter alone is insufficient because the backend already drops non-main sessions.

Actual behavior

Only main agent sessions appear in the usage page. Non-main agents are invisible to the client-side filter because they were never returned by the API. The Web UI does not send agentId in the sessions.usage request, while the backend strictly scopes lookups to the effective agent ID (default: "main").

OpenClaw version

First known bad: v2026.5.17 / commit 6a12c6f7991547c0bf82323392ca327f4de016a3 Confirmed on: v2026.5.22 Last known good: v2026.5.16 or earlier

Operating system

Any (Linux tested: Ubuntu 24.04)

Install method

npm global ([email protected])

Model

N/A (not model-specific)

Provider / routing chain

N/A

Additional provider/model setup details

N/A

Logs, screenshots, and evidence

Root cause commit: 6a12c6f7991547c0bf82323392ca327f4de016a3
- Author: pgondhi987
- Message: fix(gateway): scope session data lookups by agent [AI] (#81386)
- PR: #81386
- Changelog entry (v2026.5.17): "Gateway/sessions: scope session data lookups by agent id so multi-agent gateway state cannot cross-leak session records across configured agents."
Backend handler (src/gateway/server-methods/usage.ts, lines added by this commit):
const requestedAgentId = normalizeOptionalString$1(p.agentId);
// ...
const effectiveAgentId = normalizeAgentId(
  requestedAgentId ?? specificKeyAgentId ?? resolveDefaultAgentId(config)
);
//                           ^^^^^^^^^^^^^^^^^^^^^^^^ defaults to "main"
const scopedStore = filterSessionStoreByAgent({
  config, store, agentId: effectiveAgentId
});
Frontend controller (ui/src/ui/controllers/usage.ts:88-107) – the sessions.usage call never includes agentId:
client.request("sessions.usage", {
  startDate,
  endDate,
  ...dateInterpretation,   // mode, utcOffset
  ...usageScopeParams,     // groupBy, includeHistorical
  limit: 1000,
  includeContextWeight: true,
  // ⚠️ missing: agentId
});
The agent filter UI in ui/src/ui/views/usage.ts (renderFilterSelect("agent", ...)) only adds agent:xxx query tokens for client-side filtering – it does not affect the API parameters. This worked before v2026.5.17 because the backend had no agent-scoping.
Swift protocol was updated in the same commit (apps/shared/OpenClawKit/.../GatewayModels.swift) – SessionsUsageParams gained agentId – so the macOS native client can send the field, but the Web UI was missed.
Before this commit (9a204008ba0), usage.ts had NO requestedAgentId, filterSessionStoreByAgent, or agent-based scoping in discoverAllSessionsForUsage – all agents' sessions were returned.

Impact and severity

  • Affected: All Web UI users with multi-agent configurations who rely on the usage page to view per-agent token/cost data.
  • Severity: High (blocks the core usage-reporting workflow for non-main agents).
  • Frequency: Always – every sessions.usage call on the Web UI.
  • Consequence: Multi-agent users cannot audit usage for any agent other than main. The agent filter popover is rendered but always empty for non-main agents.

Additional information

Fix suggestion:

  1. Add usageAgentId: string | undefined to UsageState in ui/src/ui/controllers/usage.ts.
  2. Add a mechanism (e.g., a dropdown or re-use the existing query-token approach but translate agent:xxx into an API agentId param) to let the user select which agent's usage to load.
  3. Pass agentId in the client.request("sessions.usage", ...) payload: client.request("sessions.usage", { startDate, endDate, ...(state.usageAgentId ? { agentId: state.usageAgentId } : {}), ...dateInterpretation, ...usageScopeParams, limit: 1000, includeContextWeight: true, });
  4. Alternatively, if omitting agentId should return all agents' sessions (matching pre-v2026.5.17 behavior), change the backend fallback from resolveDefaultAgentId(config) to undefined (skip agent-scoping entirely when no agentId is requested). However, this would reintroduce the cross-leak concern that #81386 aimed to fix; the proper fix is to send agentId from the Web UI.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Before v2026.5.17, the sessions.usage endpoint returned sessions across all agents without agent-scoping, and the client-side agent filter could be used to narrow down results. After a regression fix, the agent filter should pass the selected agentId to the API so the backend returns the correct agent's sessions; the client-side query-based filter alone is insufficient because the backend already drops non-main sessions.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING