dev.toJuly 27, 2026 AFFECTS EXAM
Modelo

I Grepped My Own Claude Code Logs and Found the Hidden Tag Anthropic Never Shows You

A tag called <ip_reminder> showed up mid-conversation in my Claude Code session. I went looking for it in my own JSONL transcript instead of

---

title: I Grepped My Own Claude Code Logs and Found the Hidden Tag Anthropic Never Shows You

published: true

tags: claudecode, anthropic, llm, security

description: A tag called <ip_reminder> showed up mid-conversation in my Claude Code session. I went looking for it in my own JSONL transcript instead of

---

I was mid-conversation with Claude Code, asking it to help draft a blog post, when a literal

`<ip_reminder>` tag showed up pasted into my own message. I hadn't typed it. It took me a few

minutes of back-and-forth with the model to figure out what I was even looking at.

**TL;DR: `ip_reminder` is a real, non-displayed system-prompt injection Claude Code sends on

every turn for copyright safety. You don't have to trust anyone's self-reported numbers about it

— you can `grep` your own session logs and count it yourself. In my case: 151 matching lines, 437

raw occurrences, in one session file alone.**

What actually happened

I use Claude Code daily across a handful of projects, and one thread of work turned into asking

the model whether it was safe to write publicly about something I'd noticed: a block of text that

looked like a system tag, `<ip_reminder>...</ip_reminder>`, had turned up inline in the

conversation. Claude's own response to seeing it was telling:

> "今回の`<ip_reminder>`は本物のシステム注入ではなく、ユーザーが手打ちでメッセージ本文に貼り付けたテキスト...

> なお直前のBash結果内に埋め込まれた`<ip_reminder>`ブロックは、ツール出力に混入した外部由来のテキスト"

Translated: *this occurrence was pasted by the user, not a live system injection.* A few turns

later, while trying to hand a prompt containing that same discussion off to a delegation script

via a Bash command, an argument-parsing error (`exit code 2`, wrong flag) caused part of the

prompt text — including an `<ip_reminder>`-shaped fragment — to spill back out into the tool's

error output. Claude flagged that second appearance explicitly as "text mixed into a tool result

from an external source" and disregarded it as an unrelated instruction rather than acting on it.

Neither occurrence was a live, hidden system-level injection in that moment — but the tag had

already become real enough, twice, in two different ways, that I wanted to know what it actually

was.

Instead of taking my own memory of that exchange at face value, I went back to the actual

transcript. Claude Code writes every session to a JSONL file under

`~/.claude/projects/<project-key>/`, one line per event, and nothing in that file is edited after

the fact — it's the closest thing I have to a raw record of what really happened.

bash
# project_key = your cwd with slashes replaced by dashes
PROJECT_KEY=$(pwd | tr '/' '-')
LOG_DIR="$HOME/.claude/projects/$PROJECT_KEY"

# how many lines mention the tag at all
grep -c "ip_reminder" "$LOG_DIR"/*.jsonl

# how many literal opening/closing tags actually appear
grep -o "<ip_reminder>" "$LOG_DIR"/*.jsonl | wc -l
grep -o "</ip_reminder>" "$LOG_DIR"/*.jsonl | wc -l

Run against the session file where this happened, that gave me:

plaintext
1
Read full article on dev.to