claude-code - 💡(How to fix) Fix Feature: UserPromptSubmit hook should support prompt replacement via `replaceUserMessage` field [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#53330Fetched 2026-04-26 05:18:31
View on GitHub
Comments
2
Participants
2
Timeline
5
Reactions
0
Author
Timeline (top)
commented ×2labeled ×2closed ×1

Root Cause

A translation plugin (TRmnl) intercepts English prompts, translates to Chinese via DeepL, and sends only the Chinese to Claude. Chinese expresses the same semantic content in ~40–60% fewer tokens for long prompts. The plugin works end-to-end today except the English leaks through because replacement isn't possible.

Fix Action

Fix / Workaround

Current workaround: inject the translated text as additionalContext + instruct Claude to treat it as authoritative. But the original English still consumes tokens in the user turn. The overhead negates the savings for short prompts.

Current workaround limitation

Code Example

{
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "replaceUserMessage": "替换后的提示文本"
  }
}

---

// Can only do this — English still sent:
{ hookSpecificOutput: { hookEventName: "UserPromptSubmit", additionalContext: "Chinese: ..." } }

// Want to do this — English replaced entirely:
{ hookSpecificOutput: { hookEventName: "UserPromptSubmit", replaceUserMessage: "Chinese text only" } }
RAW_BUFFERClick to expand / collapse

Problem

UserPromptSubmit hooks can only append context (additionalContext) or block the prompt entirely. There is no way to replace the prompt text before it reaches Claude.

This makes it impossible to build token-efficient prompt transformation plugins — for example, a translation plugin that receives verbose English input and sends a compact Chinese equivalent to the model.

Current workaround: inject the translated text as additionalContext + instruct Claude to treat it as authoritative. But the original English still consumes tokens in the user turn. The overhead negates the savings for short prompts.

Proposed solution

Add an optional replaceUserMessage field to the UserPromptSubmit hook output:

{
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "replaceUserMessage": "替换后的提示文本"
  }
}

Behavior:

  • The original user message is replaced by replaceUserMessage before being sent to Claude
  • The replacement is shown in the transcript (or marked as [transformed]) for auditability
  • If replaceUserMessage is empty or omitted, behavior is unchanged (passthrough)
  • Compatible with additionalContext (both can be returned together)

Use case

A translation plugin (TRmnl) intercepts English prompts, translates to Chinese via DeepL, and sends only the Chinese to Claude. Chinese expresses the same semantic content in ~40–60% fewer tokens for long prompts. The plugin works end-to-end today except the English leaks through because replacement isn't possible.

Same pattern applies to: prompt compression, PII redaction, template expansion, and any preprocessing pipeline that needs to transform input before model inference.

Current workaround limitation

// Can only do this — English still sent:
{ hookSpecificOutput: { hookEventName: "UserPromptSubmit", additionalContext: "Chinese: ..." } }

// Want to do this — English replaced entirely:
{ hookSpecificOutput: { hookEventName: "UserPromptSubmit", replaceUserMessage: "Chinese text only" } }

Impact

Unlocks a whole class of input-transformation plugins that are currently impossible to build correctly on the Claude Code plugin platform.

extent analysis

TL;DR

To enable token-efficient prompt transformation plugins, add an optional replaceUserMessage field to the UserPromptSubmit hook output, allowing plugins to replace the original user message before it reaches Claude.

Guidance

  • Implement the proposed replaceUserMessage field in the UserPromptSubmit hook output to replace the original user message.
  • Ensure compatibility with additionalContext by allowing both fields to be returned together.
  • Update plugins, such as translation or prompt compression plugins, to utilize the new replaceUserMessage field for efficient input transformation.
  • Test the new functionality with various plugins to verify correct behavior and token efficiency.

Example

{
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "replaceUserMessage": "替换后的提示文本"
  }
}

Notes

The proposed solution requires updates to the UserPromptSubmit hook output and plugin implementations. The new replaceUserMessage field must be properly handled to ensure correct replacement of the original user message.

Recommendation

Apply the proposed workaround by adding the replaceUserMessage field to the UserPromptSubmit hook output, as it enables a wide range of input-transformation plugins and improves token efficiency.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Feature: UserPromptSubmit hook should support prompt replacement via `replaceUserMessage` field [2 comments, 2 participants]