hermes - 💡(How to fix) Fix Patch tool can fail or corrupt secrets when old_string is copied from redacted file output

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…

Secret redaction can make file-tool output unsafe to reuse as patch(old_string=...) input.

When security.redact_secrets: true, read_file / tool output can replace a real secret value with a shorter masked placeholder such as sk-abc...wxyz. If the agent later uses that redacted block as old_string for patch, the text no longer matches the file on disk because the raw file still contains the full-length secret.

This creates two failure modes:

  1. patch fails with old_string not found even though the agent copied the exact visible output.
  2. Worse, if the agent rewrites a surrounding YAML/JSON block, the masked placeholder can be written back into the file, replacing a valid secret with a literal shortened string and breaking auth.

Error Message

  • If detected, return a clear error explaining that redacted secret placeholders from tool output cannot be used for exact patch input.
  • Attempting to patch using a redacted block is rejected with a specific actionable error, not generic old_string not found.

Root Cause

This is a reliability footgun at the boundary between:

  • redacted content shown to the model, and
  • raw content edited on disk.

The model is encouraged to use read_file before patch, but with redaction enabled the content it sees is not always a byte-faithful representation of the file. Existing fuzzy matching handles whitespace/context drift, but it cannot infer that sk-abc...wxyz corresponds to a longer raw secret value.

Fix Action

Fix / Workaround

Secret redaction can make file-tool output unsafe to reuse as patch(old_string=...) input.

When security.redact_secrets: true, read_file / tool output can replace a real secret value with a shorter masked placeholder such as sk-abc...wxyz. If the agent later uses that redacted block as old_string for patch, the text no longer matches the file on disk because the raw file still contains the full-length secret.

  1. patch fails with old_string not found even though the agent copied the exact visible output.
  2. Worse, if the agent rewrites a surrounding YAML/JSON block, the masked placeholder can be written back into the file, replacing a valid secret with a literal shortened string and breaking auth.

Code Example

auxiliary:
  title_generation:
    api_key: sk-example-real-key-with-more-than-13-chars
    model: title-generator

---

auxiliary:
  title_generation:
    api_key: sk-exa...hars
    model: title-generator
RAW_BUFFERClick to expand / collapse

Summary

Secret redaction can make file-tool output unsafe to reuse as patch(old_string=...) input.

When security.redact_secrets: true, read_file / tool output can replace a real secret value with a shorter masked placeholder such as sk-abc...wxyz. If the agent later uses that redacted block as old_string for patch, the text no longer matches the file on disk because the raw file still contains the full-length secret.

This creates two failure modes:

  1. patch fails with old_string not found even though the agent copied the exact visible output.
  2. Worse, if the agent rewrites a surrounding YAML/JSON block, the masked placeholder can be written back into the file, replacing a valid secret with a literal shortened string and breaking auth.

Why this matters

This is a reliability footgun at the boundary between:

  • redacted content shown to the model, and
  • raw content edited on disk.

The model is encouraged to use read_file before patch, but with redaction enabled the content it sees is not always a byte-faithful representation of the file. Existing fuzzy matching handles whitespace/context drift, but it cannot infer that sk-abc...wxyz corresponds to a longer raw secret value.

Reproduction shape

Given a file like:

auxiliary:
  title_generation:
    api_key: sk-example-real-key-with-more-than-13-chars
    model: title-generator

With secret redaction enabled, the model may see something like:

auxiliary:
  title_generation:
    api_key: sk-exa...hars
    model: title-generator

If the model tries to patch the whole block to change only model, one of two bad things can happen:

  • old_string does not match raw file because api_key length/content changed by redaction; or
  • the replacement block writes api_key: sk-exa...hars back to disk.

Expected outcome: the agent can safely edit nearby non-secret fields without corrupting secrets or getting misleading patch failures.

Actual outcome: redacted tool output can be used as if it were raw file content, causing patch mismatch or secret placeholder writeback.

Suggested fixes

Possible small fix:

  • Detect masked secret placeholders in patch_tool inputs (old_string, new_string, and V4A patch payload).
  • If detected, return a clear error explaining that redacted secret placeholders from tool output cannot be used for exact patch input.
  • Suggest patching only the non-secret line or using a secret-preserving/config-aware helper.

Better longer-term fix:

  • Make redacted file output carry stable secret span metadata/placeholders that edit tools can preserve without exposing raw secret values.
  • Or provide a config/YAML edit helper that updates a specific key path while preserving raw values for adjacent secret keys.

Acceptance criteria

  • Regression test where a file contains a raw secret and read_file returns redacted content.
  • Attempting to patch using a redacted block is rejected with a specific actionable error, not generic old_string not found.
  • Attempting to write a masked secret placeholder into a file through patch/V4A is blocked or requires an explicit unsafe override.
  • Safe targeted edits to adjacent non-secret fields still work.

Related issues

Related but not duplicate of:

  • #363 — file tool output redaction gap. That issue asks for redaction coverage; this issue covers the edit-safety side effect after redaction exists.
  • #3627 — secrets tool / redaction hardening umbrella. This issue is a concrete patch/edit workflow regression risk.
  • #23200 — tool-result persistence and redacted previews. This issue is specifically about redacted output being reused as edit input.
  • #23810 — outbound chat redaction. Different boundary.

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

hermes - 💡(How to fix) Fix Patch tool can fail or corrupt secrets when old_string is copied from redacted file output