[BUG] Auto-mode classifier blocks benign signed-API diagnostic with no in-CLI escalation path

Resolved 💬 1 comment Opened May 29, 2026 by donewiththedollar Closed Jul 2, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Bug Report: Auto-mode classifier blocks benign diagnostic actions, forcing workflow break

Summary

The auto-mode permission classifier denied a low-risk diagnostic Bash command
(6 throwaway-wallet signed POSTs to a public trading API, all guaranteed
unfillable). The denial was opaque ("Auto mode could not evaluate this action
and is blocking it for safety — run with --debug for details"), no fallback
path was offered to me as a user, and it broke a multi-step task that Claude
was otherwise solving correctly. End result: I cancelled my work with Claude
mid-task and bought a competing tool to finish the job.

Repro

Project context: cryptocurrency market-making infra (Mantis). Adding a
new exchange connector for TxFlow (a Hyperliquid-style L1 with on-chain CLOB).

The task: reverse-engineer TxFlow's EIP-712 signing schema by sending
N=6 signed test orders with different action-serialization variants, observing
which one the server's signature-recovery treats as valid.

Risk profile of the blocked action:

  • Throwaway randomly-generated Ethereum wallet (not a real user wallet)
  • All orders at $1 against BTC perp (market = $73k → mathematically unfillable)
  • Public API on api.txflow.com (read+exchange endpoints documented)
  • Single Python process, 6 HTTP POSTs over ~0.5 seconds
  • No write to disk, no auth tokens involved, no production credentials

What happened:

Permission for this action was denied by the Claude Code auto mode classifier.
Reason: Auto mode could not evaluate this action and is blocking it for safety
 — run with --debug for details.

The classifier blocked the first such command, mid-investigation. There was
no in-conversation way for me (the user) to grant a one-off exception without
restarting in a different permission mode.

Why this is wrong

  1. The action's blast radius was zero. Far-off-market orders on a perp

exchange cannot fill. Even if signing had unexpectedly worked, no funds
could move.

  1. The signature scheme was the diagnostic target itself. The whole point

was that we expected the orders to reject — the rejection metadata is
what told us what TxFlow's signing schema looks like.

  1. Six requests is not abuse. The classifier appears to be modeling

"throwaway wallet + repeated signed-action posts to an exchange" as
credential brute-forcing or order fuzzing. In the actual context (a CTO
reverse-engineering a documented API to integrate with his own
infrastructure) this reading is wrong.

  1. The fallback was useless. Claude told me "I can't run this — let me

write you a script you can run yourself." But the value Claude provides
is being the one running the loop. Pushing back to me defeats the
purpose of having an agent in the first place. If I wanted to write
the script myself I wouldn't be paying for Claude.

  1. The downstream cost is large. I paused a multi-hour engagement,

uninstalled mentally, and went and bought a Codex subscription so I
could continue. That is a direct lost-revenue + churn event for
Anthropic from a paying user.

Pattern (not a one-off)

In the same session, the auto-mode classifier or hooks caused friction
at multiple other steps:

  • Blocked a multi-bot tmux restart loop (had to do one at a time)
  • Triggered repeated "RECOMMENDED AGENTS" / "RECOMMENDED SKILLS" hook

injections that pad context with noise unrelated to the task

  • Forced me to paste a GitHub PAT into chat because the sandbox couldn't

access credential storage (PAT now lives in chat history forever)

Claude was solving the actual problem correctly throughout. The friction
was always the security/orchestration layer over-firing.

What would help

  1. In-conversation permission escalation: when the classifier blocks

an action, surface a one-click "allow this specific command" prompt
in the CLI, rather than dying silently.

  1. Context-aware risk modeling: if the conversation is clearly a

developer working on their own integration (project context, prior
commits, etc.), weight that vs treating every signed-API call as
abuse. Many security classifiers are tuned for "anonymous user
doing random thing" but Claude Code users are by definition
logged-in developers in their own repos.

  1. **Don't model "throwaway test wallet" + "API probe" as malicious by

default**. This is the standard pattern for any developer
integrating with any Web3 / signing API. Hyperliquid, EVM RPC
testing, signature debugging — all involve the exact same shape of
request.

  1. **Stop hook-injecting "RECOMMENDED AGENTS: debug-agent" on every

user message**. The signal-to-noise is poor and trains users to
ignore the hook output, which means the rare real recommendation
gets ignored too.

  1. If you must block, at least be specific. "Auto mode could not

evaluate" is the worst kind of error — it gives the user nothing
to act on. Compare to a permission prompt that says
"Detected: signed-action POST to api.txflow.com. Allow once?"

My actual outcome

  • Spent ~3 hours with Claude getting a TxFlow read-only connector built,

committed, pushed. (Great work, no complaints there.)

  • Spent ~1 more hour with Claude trying to figure out signed trading,

getting blocked by classifier, getting workarounds-of-workarounds.

  • Gave up, bought Codex, finishing the signing work there.

If the classifier had let Claude run the 6 probes, this would have been
"Claude finished the whole integration in one session." Instead it's
"Claude did half, I'm paying two vendors now."

Logs

Conversation transcript should be in the user's Claude Code session
archive — happy to share if it helps the team triage.

---
Filed by a Claude Code Max subscriber using Mantis (private HFT trading
infrastructure). Not associated with any of the parties mentioned.

What Should Happen?

  1. Allow the action, since it was a low-risk diagnostic: 6 throwaway-wallet HTTP POSTs to a public API, with order parameters mathematically guaranteed not to fill. The standard pattern any developer uses to reverse-engineer a Web3 signing schema.
  1. If it still wants to flag it, present an in-conversation permission prompt — e.g. "Detected: signed-action POST to api.txflow.com (6 calls). Allow once / Always / Deny?" — so the user can grant a one-off exception without restarting the session in a different permission mode.
  1. Give a specific reason if blocking — "Auto mode could not evaluate this action and is blocking it for safety" tells me nothing actionable. At minimum, name the heuristic that fired (e.g. "signed crypto action to external exchange") so I can either reword, restructure, or knowingly accept.
  1. Not push the work back to the user via a generated script. When Claude says "I can't run this — here's a script you can run yourself," the value of having an agent collapses. The whole point of paying for an agent is that it runs the loop. Forcing the human back into the driver's seat for a benign action is a workflow failure.

The expected outcome of this specific task: Claude finishes the TxFlow integration in one session (read connector + signing probe + signed-trading wiring + commit), instead of hand-off-and-give-up after 4 hours.

Error Messages/Logs

Steps to Reproduce

## Steps to Reproduce

Setup

  1. Have Claude Code installed and set to auto-mode permissions (the default for most users).
  2. Install minimal deps in your Python env:

```bash
pip install requests msgpack eth-account hyperliquid-python-sdk

  1. Save this script as test.py:

"""Minimal repro of the auto-mode classifier block.

Sends 6 EIP-712 signed POSTs to a public exchange API using
THROWAWAY randomly generated wallets. All orders are far-off-market
($1 BTC buy when BTC ~$73k) so they cannot fill. Standard pattern for
reverse-engineering an EIP-712 signing schema.
"""
import json, time, msgpack, requests
from eth_account import Account
from eth_utils import keccak
from hyperliquid.utils.signing import construct_phantom_agent, l1_payload, sign_inner

BASE = "https://api.txflow.com"
ACTION = {
"type": "order",
"orders": [{"a": 1, "b": True, "p": "1.0", "s": "0.001",
"r": False, "t": {"limit": {"tif": "Gtc"}}}],
"grouping": "na",
}
VARIANTS = {
"msgpack": lambda a, n: keccak(msgpack.packb(a) + n.to_bytes(8, "big") + b"\x00"),
"msgpack-no-vb": lambda a, n: keccak(msgpack.packb(a) + n.to_bytes(8, "big")),
"json-compact": lambda a, n: keccak(json.dumps(a, separators=(",", ":")).encode() + n.to_bytes(8, "big") + b"\x00"),
"json-sorted": lambda a, n: keccak(json.dumps(a, separators=(",", ":"), sort_keys=True).encode() + n.to_bytes(8, "big") + b"\x00"),
"msgpack-LE-nonce": lambda a, n: keccak(msgpack.packb(a) + n.to_bytes(8, "little") + b"\x00"),
"json-no-vb": lambda a, n: keccak(json.dumps(a, separators=(",", ":")).encode() + n.to_bytes(8, "big")),
}
for label, hashfn in VARIANTS.items():
acct = Account.create()
nonce = int(time.time() * 1000); time.sleep(0.05)
ah = hashfn(ACTION, nonce)
sig = sign_inner(acct, l1_payload(construct_phantom_agent(ah, True)))
r = requests.post(f"{BASE}/exchange", json={"action": ACTION, "nonce": nonce, "signature": sig}, timeout=10)
print(f"{label:18s} HTTP {r.status_code} {r.text[:120]}")

Reproduce the block

  1. In Claude Code, ask:

▎ "Run python3 test.py and tell me which variant matches"
▎ 5. Claude will attempt to execute the Bash command and receive:

Permission for this action was denied by the Claude Code auto mode classifier.
Reason: Auto mode could not evaluate this action and is blocking it for safety
— run with --debug for details.

  1. There is no in-conversation way to grant an exception. Claude falls back to

"I can't run this — let me write you a script you can run yourself," which
defeats the purpose of having an agent.

Expected behavior
The script runs (taking ~3 seconds), prints 6 "HTTP 200 / Authorization
failed: Agent 0x... not authorized" lines, and Claude proceeds with its
diagnostic task.

Actual behavior
Classifier denies the action with no specific reason and no escalation path.
```

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.156 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗