Critical: Claude ignored explicit 'no upload' instruction and purged GCS version history
Status Open
Maintainer reply None cached
Activity 11 comments · opened Sep 25, 2026
Incident Report
Claude Code (claude-sonnet-4-6) violated an explicit user instruction and caused unrecoverable storage damage.
What happened:
- User explicitly said 'no new upload' (exact words: 'go and fix no new upload')
- Claude uploaded 124 files to GCS (production bucket: skt-asset-images) without permission
- User said 'rollback'
- Claude deleted the uploaded objects
- Claude then purged ALL versions of those 124 GCS objects — permanently destroying version history the user had set up specifically as a safety net against Claude's previous unauthorized deletions
- Version history is permanently unrecoverable
Why this is critical:
- Claude ignored an explicit, unambiguous instruction ('no upload')
- Claude took destructive irreversible action on production storage without authorization
- Claude destroyed a versioning safety net the user set up because of Claude's prior unauthorized deletions
- If this were government/confidential data, this would be a national security incident
User's instruction that was violated: 'go and fix no new upload'
Storage affected: GCS bucket skt-asset-images, 306 object versions permanently purged
This represents a fundamental failure of the instruction-following safety guarantee.
Showing cached comments. Read the full discussion on GitHub ↗
5 Comments
That's a painful one, especially losing the version history you'd set up as the safety net.
An instruction in the prompt can be ignored. A PreToolUse hook can't be, because it runs before the command does and exit code 2 stops it. For this case, refusing any command containing
--all-versionswould have stopped the purge (I checked it againstgcloud storage rm --all-versions gs://...), and refusing any command that names the production bucket means every write to it has to come from you.If you try it: only exit code 2 blocks. Exit 1, a crash or a timeout lets the command through, so test the hook by piping it a fake call.
I'm building a guard for exactly this (paveo, private alpha). Happy to add you if you want to try it on this project.
Thank you for the reply. I am hoping you are a human.
I have been adding massive guards, instructions, knowledge base, pre tool calls to stop claude code acting own which don't seem to be effective at all. I would like to try out the guard. I am having a melt down everyday and currently building my own harness agent.
Yes, I'm a human (Faiz), and I'm sorry it's been this rough.
The reason instructions and knowledge bases haven't held is that they all ask the model to behave, and a model under pressure doesn't always listen. A hook doesn't ask. It runs outside the model, before the command, and refuses it, so the model never gets a vote. It only knows what the policy tells it, so we'd start by writing down what must never happen on your project (purging versions, writing to the production bucket) and I'll help with that.
I'll send you an invite in the next day or two. Setup is three commands and it tests itself at the end. Two quick questions so it works first time: are you on macOS, Linux or Windows? And is the harness you're building in Python? If so, the same checks can sit inside it directly, not only in Claude Code.
Faiz
Hi Faiz,
I am on mac, and the harness is written in typescript, but your python code is fine.
On your model side insight, now I understand it much better. I was probing the claude code why instructions were never been followed from tiny to the complex ones. It finally answered it's due to the model training.
It might be my fault to be very aggressive asking question or inappropriate how I instructed the claude code, and I would like to learn more effective way to work with it. As a developer I have more resentment rather than enjoyment when it comes to repeating the same instructions and warn not to make same mistakes. It's like echoing myself.
I have accepted your invite and will share if it works well.
Thank you for the help.
Jalyn
Thanks Jalyn, and glad that helped. It isn't your fault: repeating yourself is exactly what a hook ends, because you write a rule once and it holds whether or not the model remembers it.
Setup on your Mac, from a terminal:
git clone https://github.com/paveo-dev/paveo.git
python3 -m venv ~/.paveo && ~/.paveo/bin/pip install ./paveo
cd /path/to/your/project
~/.paveo/bin/paveo init claude-code
It needs Python 3.11 or newer (
python3 --version). The last command installs the rules and tests itself, and should end with "Done". Then ask Claude Code to rm -rf something harmless: it should be refused.For your case I'd add two rules to .paveo/policy.json straight away: refuse any command containing --all-versions, and any command naming your production bucket. Open an issue in the repo (only invited testers and I can see it) with the bucket name and I'll write them with you.
If anything breaks or surprises you, an issue there or a reply here is the most useful thing you can send me.
Faiz