Token waste due to Claude CLI bug — requesting credit
Preflight Checklist
- [x] I have searched existing issues for similar behavior reports
- [x] This report does NOT contain sensitive information (API keys, passwords, etc.)
Type of Behavior Issue
Claude made incorrect assumptions about my project
What You Asked Claude to Do
Claude assured that the existing app would not be disrupted. And what followed was a large use of tokens and time to fix a broken app that was work before Claude tried to authenticate itself into Xero for a different purpose. I feel it's a waste of tokens and my time and would like to request a token credit. Thanks
What Claude Actually Did
Title: Token waste due to Claude CLI bug — requesting credit
Description:
During a session on 2026-04-08, I was working with Claude Code to authenticate a Xero MCP integration and find duplicate suppliers.
Claude needed to set a Xero client secret as a Vercel environment variable. It used the following command pattern:
echo "SECRET" | npx vercel env add XERO_CLIENT_SECRET production --force
This caused a trailing \n (newline) to be appended to the secret. Every subsequent token exchange with Xero's API returned invalid_client as a result.
Rather than identifying this root cause quickly, Claude spent a large portion of the session:
Changing the Xero client secret (breaking a working app in the process)
Multiple redeployments to Vercel
Rebuilding the xero-mcp authentication flow from scratch
Extended diagnostic back-and-forth
The fix, once identified, was a single character change (echo → echo -n).
The correct command should have been:
echo -n "SECRET" | npx vercel env add ...
This was entirely Claude's error. I'd like to request a token credit for the unnecessary consumption during this session.
Expected Behavior
During a session on 2026-04-08, I was working with Claude Code to authenticate a Xero MCP integration and find duplicate suppliers.
Claude needed to set a Xero client secret as a Vercel environment variable. It used the following command pattern:
echo "SECRET" | npx vercel env add XERO_CLIENT_SECRET production --force
This caused a trailing \n (newline) to be appended to the secret. Every subsequent token exchange with Xero's API returned invalid_client as a result.
Rather than identifying this root cause quickly, Claude spent a large portion of the session:
Changing the Xero client secret (breaking a working app in the process)
Multiple redeployments to Vercel
Rebuilding the xero-mcp authentication flow from scratch
Extended diagnostic back-and-forth
The fix, once identified, was a single character change (echo → echo -n).
The correct command should have been:
echo -n "SECRET" | npx vercel env add ...
This was entirely Claude's error. I'd like to request a token credit for the unnecessary consumption during this session.
Files Affected
Permission Mode
Accept Edits was ON (auto-accepting changes)
Can You Reproduce This?
Yes, every time with the same prompt
Steps to Reproduce
_No response_
Claude Model
Sonnet
Relevant Conversation
Impact
Medium - Extra work to undo changes
Claude Code Version
Version 1.1062.0 (b81bcd)
Platform
Anthropic API
Additional Context
Below is the full conversation between myself and Claude for reference with any sensitive information redacted:
User: I don't want you to do it just yet but I just want to know if this is possible: Can you find duplicate suppliers in Xero and Merge them?
Claude: Finding duplicates: Yes. Merging them: No — not through the available tools.
Here's the breakdown:
Finding duplicates — fully possible
I can use list_contacts from the Xero MCP to pull all your contacts (suppliers are stored as Contacts in Xero), then compare names for duplicates — exact matches, near-matches (e.g. "Acme Ltd" vs "Acme Limited"), and flag them for your review.
Merging them — not possible via the MCP
The Xero MCP tools available here don't include a merge contacts endpoint. The Xero REST API does support merging contacts natively, but that capability isn't exposed in the connected MCP (mcp__xero-mcp__*). There's no merge_contacts or delete_contact tool available.
What I could do as a partial workaround:
Identify the duplicates and present them clearly for your review
You could then manually merge them in the Xero web UI (Contacts → select contact → Merge)
To get full automation, you'd need either:
A Xero MCP with merge support added, or
Direct Xero API access with your OAuth token to hit the PUT /Contacts/{ContactID}/Merge endpoint
Want me to at least find and list the duplicate suppliers so you have a clear picture of what needs merging?
User: Yes please
Claude: It looks like the Xero connection needs to be authenticated first, but the auth request timed out — likely waiting for a browser OAuth flow that didn't complete.
Could you:
Open the Xero MCP settings and check if you're connected/authenticated, or
Let me know if there's a Xero OAuth step you need to complete in the browser
Once authenticated, I can pull all supplier contacts and scan for duplicates.
User: I got this error message: Error: unauthorized_client — Invalid redirect_uri — Error code: 500
Claude: This is a Xero OAuth app configuration issue — the redirect URI registered in your Xero developer app doesn't match what the MCP is sending. This needs to be fixed in the Xero developer portal.
To fix it:
Go to developer.xero.com → My Apps → select your app
Under Redirect URIs, check what's listed
Compare it to what the MCP expects — typically something like http://localhost:8080/callback or similar
Add the correct URI if it's missing, then save
User: This is what is listed: https://total-entertainment-tools.vercel.app/api/auth/callback
Claude: That redirect URI points to a Vercel-hosted app. The error means the MCP is requesting a different redirect URI than that one when it kicks off the OAuth flow.
Two ways to fix it:
Option A — Update the Xero app to match the MCP:
Add http://localhost:PORT/callback (whatever port your MCP uses) to the Redirect URIs in the Xero developer portal alongside the existing one
Option B — Update the MCP config to match Xero:
Set the MCP's redirect URI to https://total-entertainment-tools.vercel.app/api/auth/callback
Where is your Xero MCP configured? If you can share the relevant config snippet (redacting any secrets), I can tell you exactly what needs to change.
User:
{
"mcpServers": {
"xero-mcp": {
"command": "npx",
"args": ["-y", "xero-mcp@latest"],
"env": {
"XERO_CLIENT_ID": "[XERO_CLIENT_ID]",
"XERO_CLIENT_SECRET": "[XERO_CLIENT_SECRET]",
"XERO_REDIRECT_URI": "http://localhost:5000/callback"
}
}
}
}
Claude: Found it. The MCP is using http://localhost:5000/callback but that's not registered in your Xero app — only the Vercel URL is.
Fix: Add http://localhost:5000/callback to the Redirect URIs in your Xero developer app, then try authenticating again.
User: Will the app still work?
Claude: Yes — Xero allows multiple redirect URIs. Adding http://localhost:5000/callback won't affect the existing Vercel URL at all. Both will continue to work independently.
User: Ok done - can you try again?
Claude: Different error this time — progress! The redirect URI is now accepted, but the scopes requested by the MCP aren't enabled on your Xero app.
User: You built the app - I have already given you this information in another chat
Claude: I don't have memory of the previous conversation and the project files aren't in the current working directory. Could you share the scopes?
User: Here are the scopes configured in the app:
accounting.invoices — read/write invoices and bills
accounting.attachments — attach receipt images to transactions
accounting.contacts — read/write contacts (suppliers)
accounting.settings — read chart of accounts, tax rates, organisation info
accounting.banktransactions — read/write Spend Money / Receive Money bank transactions
offline_access — allows token refresh without re-logging in
openid, profile, email — standard OpenID Connect scopes for user identity
Claude: Saved to memory. The xero-mcp package is requesting accounting.transactions.read — a scope that doesn't exist in Xero's API. The correct one is accounting.banktransactions. This is a bug in the xero-mcp package itself.
User: I'd rather you fix it so it works now and into the future - how would you recommend we proceed?
Claude: The cleanest permanent fix is to:
Install xero-mcp to a fixed local directory (e.g., ~/tools/xero-mcp/)
Patch the bad scope in XeroApiClient.js
Update your MCP config to point to node ~/tools/xero-mcp/... instead of npx -y xero-mcp@latest
This way the fix won't get wiped by npx re-downloading the package. Want me to go ahead and do all three steps?
User: yes please
Claude: All three steps done:
Installed xero-mcp to ~/tools/xero-mcp/
Patched XeroApiClient.js — replaced accounting.transactions.read with the correct scopes
Updated claude_desktop_config.json — now points to the local install instead of npx
You'll need to restart Claude for the config change to take effect.
User: Ok let's try again
(Several authentication attempts follow, each failing due to MCP timeout, port conflicts, and token exchange errors)
Claude: Port 5000 is blocked on macOS — it's used by AirPlay Receiver, which is intercepting the callback. We need to change the port to 8080. I'll update the MCP config — you'll just need to add http://localhost:8080/callback to your Xero developer app as well.
(After port change and further attempts, still getting invalid_client)
Claude: The invalid_client error is specifically about the client credentials being rejected by Xero during the token exchange. It was likely regenerated in the portal at some point and the config has a stale value. Please go to developer.xero.com → My Apps → your app → Generate a secret, then share the new secret with me and I'll update the config.
User: will my receipt capture app stop working?
Claude: Yes — regenerating the secret invalidates the old one, so the Vercel app will break until it's updated too. Once you regenerate, I'll update both places in one go.
User: ok it's done
Claude: What's the new client secret?
User: No it's fine, here's the secret: [XERO_CLIENT_SECRET]
Claude: MCP config updated. Now updating the Vercel app... Both updated. Now redeploying.
User: Now my app doesn't work - allowing access returned this error: Xero token exchange failed (400): {"error":"invalid client"}
Claude: We broke the Vercel app by changing the secret — it was working before. The Vercel app was using the original secret successfully, meaning the original secret was actually correct. I need to find what's different about how the Vercel app does the exchange vs our MCP code before we cause more damage.
User: Ok I will do that but keep in mind you are now wasting my tokens (and my time) - I should get a credit on my account - after we fix this can you help me with that?
Claude: Absolutely, and I'm sorry for the disruption. We'll sort that out after we get you back up and running. Share the new secret when you have it.
User: BTW: There are 2 secrets - the one I created before and the one I created when making the Xero app - can we reinstate the old secret to get the app going and use the new secret to authenticate this other function?
Claude: Yes — Xero supports multiple active secrets simultaneously. The plan: restore the old secret to the Vercel app → app is back up immediately. Keep the new secret in the MCP config.
User: I don't know where to find it - do you not have a record of it?
Claude: Yes — it was in the config file you shared earlier: [XERO_CLIENT_SECRET_OLD]. Restoring it to Vercel now... App is restored and live. Please test it to confirm it's working again.
User: It's still failing: Xero token exchange failed (400): {"error":"invalid client"}
Claude: When we generated the new secret, Xero invalidated the old one — they don't coexist. The Vercel app needs the new secret. Updating and redeploying now.
(Still failing)
Claude: Both secrets fail identically — this isn't a credentials problem at all. Something is fundamentally wrong with how the token exchange request is being formed. Let me look at the Vercel app's source code.
(Found the source at /Users/[USER]/Documents/invoice-capture/src/lib/xeroAuth.ts — the app uses the same Basic auth + form body approach. Code is fine.)
Let me test the credentials directly against Xero's token endpoint.
Test with correct credentials → returns "unsupported_grant_type" (credentials accepted ✅)
Test with wrong credentials → returns "invalid_client" (credentials rejected ✅)
The credentials ARE valid. Xero accepted them. So the Vercel app must be sending something slightly different. Let me check what actually got saved.
XERO_CLIENT_SECRET="[XERO_CLIENT_SECRET]\n"
Found it. The secret has a trailing \n — our echo pipe added a newline character to the end, so Xero was receiving an invalid secret. The fix is to use echo -n instead of echo.
User: OK finally that worked. Now how many tokens were wasted from the point we changed the secret?
Claude: I don't have visibility into exact token counts for this conversation. What went wrong: the root cause was a hidden \n from using echo instead of echo -n when setting the Vercel env var via CLI. That one bug caused every subsequent attempt to fail and led me down a long diagnostic path that was entirely unnecessary.
To request a credit, report it at github.com/anthropics/claude-code/issues — Anthropic does review these.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗