Skip to content

fix: resolve critical token tracking bug caused by PowerShell $args collision#111

Merged
ooples merged 3 commits intomasterfrom
fix/token-tracking-args-collision
Oct 31, 2025
Merged

fix: resolve critical token tracking bug caused by PowerShell $args collision#111
ooples merged 3 commits intomasterfrom
fix/token-tracking-args-collision

Conversation

@ooples
Copy link
Copy Markdown
Owner

@ooples ooples commented Oct 31, 2025

Summary

This PR fixes the critical token tracking bug that caused 100% failure rate (49,578+ operations with 0 tokens tracked).

Root Cause

The PowerShell parameter named $Args in invoke-mcp.ps1 conflicted with PowerShell's automatic $args variable, causing all MCP tool arguments to become empty {} objects.

Investigation Process

  • Created 3 expert AI agents for multi-angle analysis
  • Used Gemini CLI (2M token context) for comprehensive codebase analysis
  • Performed deep web research on PowerShell automatic variables
  • Analyzed git history to trace bug introduction
  • All approaches independently converged on the same root cause

The Fix

File: hooks/helpers/invoke-mcp.ps1

  1. Line 73: Renamed parameter from $Args$ToolArguments

    • Avoids collision with PowerShell's automatic $args variable
  2. Lines 84-87: Removed unnecessary [PSCustomObject] casting

    • PowerShell Hashtables serialize correctly to JSON objects natively
    • Previous casts were masking the real issue

Evidence

Before Fix (from MCP invocation logs):

[DEBUG] Arguments content: {"enableCache":true,"path":"...","includeMetadata":true}
[DEBUG] Request: {"arguments":{}}  ← EMPTY!

After Fix:

[DEBUG] Arguments content: {"enableCache":true,"path":"...","includeMetadata":true}
[DEBUG] Request: {"arguments":{"enableCache":true,"path":"...","includeMetadata":true}}  ← POPULATED!

Documentation Improvements

File: README.md

Added comprehensive section explaining where users can find actual token savings:

  • Clarified that current-session.txt only shows operation counts, NOT savings
  • Added clear instructions to use get_session_stats() tool for savings data
  • Provided example output showing totalTokensSaved field
  • Added warning annotations to prevent user confusion

Impact

  • Before: 0 tokens tracked across 49,578+ operations (100% failure)
  • After: All MCP tool calls now properly receive arguments and track tokens
  • User Experience: Users can now see accurate token savings via get_session_stats()

Testing

✅ Live testing in C:\Users\cheat\.claude-global\hooks\helpers\invoke-mcp.ps1 shows:

  • Arguments properly serialized in JSON requests
  • MCP tools receiving correct parameters
  • Token tracking functioning as designed

Related Issues

This fixes the recurring token tracking issue that was partially addressed in commits:

The $Args collision was the underlying cause that previous fixes didn't identify.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Oct 31, 2025

Summary by CodeRabbit

  • Documentation

    • Enhanced Real-Time Session Monitoring documentation with detailed output examples showing token savings metrics, including cache hit rates and per-tool breakdowns.
    • Clarified that session files record operation counts; actual savings must be retrieved via get_session_stats for accurate reporting.
    • Renamed "Session Logs" to "Session Tracking Files" and updated associated descriptions.
  • Bug Fixes

    • Fixed parameter handling in helper scripts to prevent conflicts and improve robustness.

Walkthrough

Documentation clarifies that token savings require an explicit get_session_stats() call and renames session logs to session tracking files; PowerShell helper Invoke-MCP renamed its $Args parameter to $ToolArguments and JSON argument handling was simplified; minor TypeScript and validation formatting changes applied.

Changes

Cohort / File(s) Summary
Documentation
README.md
Replaced generic session-monitoring guidance with explicit get_session_stats() usage; added detailed JSON "Example Output" (totalTokensSaved, tokenReductionPercent, originalTokens, optimizedTokens, cacheHitRate, per-tool breakdown); renamed “Session Logs” → “Session Tracking Files”; clarified session file records operation counts and noted CSV logging is planned.
PowerShell helper
hooks/helpers/invoke-mcp.ps1
Renamed parameter $Args$ToolArguments; added null-check and default to empty hashtable; removed PSCustomObject coercion for nested hashtables and simplified JSON building; updated call sites to pass -ToolArguments.
Server TypeScript
src/server/index.ts
Replaced // @ts-ignore with // @ts-expect-error in the CallToolRequestSchema handler and reformatted validation error construction for readability; no runtime behavior changes.
Token/count logic formatting
src/core/token-counter.ts
Reworked multi-line formatting for model selection and Claude→gpt-4 mapping condition; logic unchanged.
Validation schemas
src/validation/tool-schemas.ts, src/validation/validator.ts
Converted many object-literal keys in toolSchemaMap from quoted strings to unquoted identifiers (hyphenated keys remain quoted); minor formatting changes to schema chaining and error message lambda formatting; semantics unchanged.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Verify all PowerShell call sites were updated to use -ToolArguments (search for previous -Args usage).
  • Test nested-hashtable JSON serialization in PowerShell environments the project supports.
  • Confirm README Example Output fields match actual get_session_stats() structure and names.

Possibly related PRs

Poem

🐰
I hopped through docs and scripts tonight,
Renamed a param to keep things light.
JSON hums without the old cast,
Stats fetched clearly, errors past.
Carrots, clean code, and hops — delight.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "fix: resolve critical token tracking bug caused by PowerShell $args collision" clearly and specifically identifies the main change in this pull request. It uses the conventional commit format ("fix:") and accurately captures the primary objective: resolving a critical bug where a PowerShell parameter named $Args conflicted with the automatic $args variable, causing token tracking to fail across 49,578+ operations. The title is concise, descriptive, and directly related to the most significant changes in the codebase (the parameter rename in invoke-mcp.ps1 and related documentation updates in README.md).
Description Check ✅ Passed The PR description is comprehensive and covers all critical information needed to understand the changes, though it deviates from the template's structured format. The description includes a clear summary of the bug, root cause analysis, detailed investigation process, specific file changes, evidence with before/after logs, documentation improvements, impact assessment, and testing confirmation. While it doesn't follow the template's checkbox-based sections (Type of Change, Testing, Checklist), the actual content addresses these areas substantively in prose form. The description is notably detailed and specific, providing sufficient context for reviewers to understand both the technical issue and its resolution.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/token-tracking-args-collision

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12619c9 and e81da2e.

📒 Files selected for processing (4)
  • src/core/token-counter.ts (2 hunks)
  • src/server/index.ts (2 hunks)
  • src/validation/tool-schemas.ts (8 hunks)
  • src/validation/validator.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/validation/validator.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/server/index.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Integration Tests
  • GitHub Check: Test (Node 18)
  • GitHub Check: Test (Node 20)
🔇 Additional comments (4)
src/core/token-counter.ts (2)

17-21: LGTM! Improved readability.

The multi-line formatting of the model assignment improves readability while preserving the same fallback logic.


38-43: LGTM! Improved readability.

The multi-line formatting of the conditional makes the Claude model detection logic clearer.

src/validation/tool-schemas.ts (2)

10-15: LGTM! Improved readability.

The multi-line formatting of schema definitions improves readability and makes the chaining structure clearer throughout the file.

Also applies to: 31-36, 49-49, 61-66, 71-83, 88-111, 122-126, 136-140, 235-262, 265-299


342-409: LGTM! Cleaner object key syntax.

Switching to unquoted keys for valid JavaScript identifiers is cleaner and more idiomatic. Hyphenated keys (lines 403-408) correctly remain quoted as required by JavaScript syntax.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

Commit Message Format Issue

Your commit messages don't follow the Conventional Commits specification.

Required Format:

<type>(<optional scope>): <description>

[optional body]

[optional footer]

Valid Types:

  • feat: A new feature
  • fix: A bug fix
  • docs: Documentation only changes
  • style: Changes that don't affect code meaning (white-space, formatting)
  • refactor: Code change that neither fixes a bug nor adds a feature
  • perf: Code change that improves performance
  • test: Adding missing tests or correcting existing tests
  • build: Changes that affect the build system or external dependencies
  • ci: Changes to CI configuration files and scripts
  • chore: Other changes that don't modify src or test files
  • revert: Reverts a previous commit

Examples:

feat(auth): add OAuth2 authentication
fix(api): resolve race condition in token refresh
docs(readme): update installation instructions
refactor(core): simplify token optimization logic

Breaking Changes:

Add BREAKING CHANGE: in the footer or append ! after the type:

feat!: remove deprecated API endpoints

Please amend your commit messages to follow this format.

Learn more: Conventional Commits

1 similar comment
@github-actions
Copy link
Copy Markdown

Commit Message Format Issue

Your commit messages don't follow the Conventional Commits specification.

Required Format:

<type>(<optional scope>): <description>

[optional body]

[optional footer]

Valid Types:

  • feat: A new feature
  • fix: A bug fix
  • docs: Documentation only changes
  • style: Changes that don't affect code meaning (white-space, formatting)
  • refactor: Code change that neither fixes a bug nor adds a feature
  • perf: Code change that improves performance
  • test: Adding missing tests or correcting existing tests
  • build: Changes that affect the build system or external dependencies
  • ci: Changes to CI configuration files and scripts
  • chore: Other changes that don't modify src or test files
  • revert: Reverts a previous commit

Examples:

feat(auth): add OAuth2 authentication
fix(api): resolve race condition in token refresh
docs(readme): update installation instructions
refactor(core): simplify token optimization logic

Breaking Changes:

Add BREAKING CHANGE: in the footer or append ! after the type:

feat!: remove deprecated API endpoints

Please amend your commit messages to follow this format.

Learn more: Conventional Commits

@github-actions
Copy link
Copy Markdown

Performance Benchmark Results


Renamed parameter from $Args to $ToolArguments in invoke-mcp.ps1 to avoid
collision with PowerShell's automatic $args variable.

The $Args collision caused all MCP tool arguments to serialize as empty {}
objects, resulting in 100% token tracking failure (49,578+ operations with
0 tokens tracked).

Investigation process:
- Created 3 expert AI agents for multi-angle analysis
- Used Gemini CLI (2M token context) for comprehensive codebase analysis
- Performed deep web research on PowerShell automatic variables
- All approaches independently converged on the same root cause

Changes:
- Line 73: Renamed $Args → $ToolArguments
- Lines 84-87: Removed unnecessary [PSCustomObject] casting
- PowerShell Hashtables serialize correctly to JSON objects natively

Evidence from MCP invocation logs:
Before: Arguments content: {...} but Request: {"arguments":{}} (EMPTY)
After: Arguments content: {...} and Request: {"arguments":{...}} (POPULATED)

This fixes the recurring issue partially addressed in:
- d38efe0 (removed casts but missed parameter name issue)
- 1a3da5e (PR #110 - attempted fix but root cause remained)
@ooples ooples force-pushed the fix/token-tracking-args-collision branch from f415b8a to 72b4e42 Compare October 31, 2025 15:56
@github-actions
Copy link
Copy Markdown

Performance Benchmark Results


Fixes ESLint @typescript-eslint/ban-ts-comment error at line 633 in src/server/index.ts.
The @ts-expect-error directive is preferred over @ts-ignore because it will error if
the suppressed issue is resolved, preventing dead suppression comments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Performance Benchmark Results


Fixes Prettier formatting errors in 4 files to pass CI lint check:
- src/core/token-counter.ts
- src/server/index.ts
- src/validation/tool-schemas.ts
- src/validation/validator.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Performance Benchmark Results


@ooples ooples merged commit 4d5a0c5 into master Oct 31, 2025
16 checks passed
@ooples ooples deleted the fix/token-tracking-args-collision branch October 31, 2025 17:46
@github-actions
Copy link
Copy Markdown

This PR is included in version 4.0.1. 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant