Skip to content

Unified session report drops Claude sessions that continue past --until #2016

Closed

Description

@igorovh

What happened?

ccusage session --until X keeps a Claude session only when its last activity is on or before day X. A session that continues after X disappears from the report entirely, including the usage it had inside the window.

ccusage claude session with the same window handles this differently: it filters entries by date first and then builds sessions, so the same session shows its in-window usage.

On my data for --since 20261030 --until 20261101:

Command Claude sessions Cost
ccusage claude session 62 $520.34
Claude part of ccusage session 48 $368.87

All 14 missing sessions have usage after the --until day (after local midnight), and none of the 48 included ones do. The missing usage inside the window is about $151.

Because of this, ccusage claude session + ccusage opencode session can't add up to ccusage session, while the daily-family reports do add up.

Steps to reproduce

  1. Have a Claude Code session with usage on day X that continues after midnight.
  2. Run ccusage claude session --until X --json: the session is listed, with its usage from day X.
  3. Run ccusage session --until X --json: the session is missing.

Expected behavior

The unified session report counts the same in-window usage as ccusage claude session, so focused reports add up to the unified one.

I know #2007 describes whole-session totals as intended, so I'd like to check first: should the unified report filter Claude entries by date like the focused report? If yes, I can implement it, and the OpenCode Claude Agent matching in unified session reports would then switch to session-day matching too.

Version

v20.0.48

Activity

  1. pullfrog commented on Nov 2, 2026

    @pullfrog
    Contributor
  2. added
    bugSomething isn't working
    priority:mediumA normal bug or meaningful improvement.
    triage:maintainableFits the repository's maintainable scope and needs review.
    on Nov 2, 2026
  3. added
    priority:highHigh user impact or an important regression.
    and removed
    priority:mediumA normal bug or meaningful improvement.
    on Nov 2, 2026
  4. github-actions commented on Nov 2, 2026

    @github-actions
    Contributor

    Pullfrog triage: priority:high
    Kind: bug
    Maintenance fit: maintainable
    Confidence: high

    Unified session drops Claude sessions continuing past --until, omitting in-window usage that focused claude session includes. Report shows 14 missing sessions and about $151 missing cost on the same window, so focused reports do not add up to unified. This is material cost misreporting and cross-command incompatibility.

    Decision: kept open; Pullfrog will attempt a focused implementation PR.

  5. igorovh commented on Nov 4, 2026

    @igorovh
    ContributorAuthor

    I have a fix for this on my fork. Unfortunately I don't have permission to open PRs here yet (GitHub rejects createPullRequest for my account), so I'm leaving the branch for now. As soon as I get permission, I'll open the PR:

    main...igorovh:ccusage:fix/unified-session-date-window

    What it changes

    • In unified session reports, Claude entries are filtered by date before sessions are built, the same way ccusage claude session and the other unified sources already do it. A session that continues past --until now shows its in-window usage instead of disappearing, and a session started before --since no longer brings its earlier usage along.
    • OpenCode claude-agent rows (fix(all): count OpenCode Claude Agent turns once in unified reports #2007) still match by whole session, so a turn that crosses midnight is counted once. Only sessions with in-window Claude usage count now, and a row is skipped only when its date is also inside the Claude source's date range.
    • DedupedEntries now keeps the index of the kept entry for each merged copy (resumed or forked transcripts), so the copy's session counts on the same day as the kept entry, as in the daily loader. main_thread_sessions is replaced by main_thread_session_days.

    Is it fixed? Examples

    My real data, --since 20261030 --until 20261101:

    Before (v20.0.48) After
    Claude part of ccusage session 48 sessions, $368.87 62 sessions, $520.34
    ccusage claude session 62 sessions, $520.34 62 sessions, $520.34
    OpenCode part of ccusage session $454.91 $171.26
    ccusage session total $823.78 $691.60
    ccusage daily total $691.60 $691.60

    The Claude part now matches ccusage claude session exactly, and the unified session total equals the unified daily total (cache read matches to the token). The OpenCode part dropped because the Claude Agent turns of the 14 previously missing sessions were kept under OpenCode, priced from the opus alias, and are now counted once under Claude.

    Minimal repro (new CLI test unified_sessions_count_the_in_window_usage_of_a_session_active_past_until): one session with $1 on 2026-09-11 23:30 UTC and $2 on 2026-09-12 00:30 UTC, reported with --since 20260911 --until 20260911 --timezone UTC:

    Command Before After
    ccusage claude session $1.00 $1.00
    ccusage session $0.00 $1.00

    I checked that the test fails without the fix (left: 0, right: 1.0) and passes with it.

    Behavior change

    ccusage session --since X no longer counts usage from before X for sessions that started earlier. bounded_unified_sessions_keep_old_subagent_files asserted that (a subagent from 2026-09-01 with --since 20260910 added $2), so I renamed it to bounded_unified_sessions_count_only_in_window_usage_of_old_subagent_files, and it now expects $1, matching ccusage claude session.

    Tests

    • New: the CLI test above, plus unified_session_counts_a_claude_agent_session_active_past_until_once in adapter-all.
    • The fix(all): count OpenCode Claude Agent turns once in unified reports #2007 tests for the midnight crossing, a mixed session, and a per-source Claude window pass unchanged.
    • cargo clippy --workspace --all-targets -- -D warnings and cargo fmt --check are clean. 4 existing tests fail on Windows only (http cache dir, two statusline tests, and the Antigravity path separator). This change doesn't touch their code, but I haven't run them on a clean main.
  6. added a commit that references this issue on Nov 10, 2026
    5f31039
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:highHigh user impact or an important regression.triage:maintainableFits the repository's maintainable scope and needs review.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions