Thanks to visit codestin.com
Credit goes to github.com

Skip to content

--cache-strategy content silently falls back to size-only comparison (casing mismatch with file-entry-cache v11) #18913

@paulofduarte

Description

@paulofduarte

Description

--cache-strategy content does not enable content hashing. A property name casing mismatch between Prettier and file-entry-cache v11 causes the option to be silently ignored, leaving file size as the only change-detection check. Any file modification that preserves the byte count is invisible to the cache.

This also affects the default behaviour (no --cache-strategy flag), since the default is content.

Root cause

In src/cli/format-results-cache.js (line 46–48), Prettier passes:

const useChecksum = cacheStrategy === "content";   // lowercase 's'
const fileEntryCacheOptions = {
  useChecksum,          // ← lowercase 's'
  useModifiedTime: !useChecksum,
};

But file-entry-cache v11.1.2 reads options?.useCheckSum (capital S):

// file-entry-cache v11 — constructor
if (options?.useCheckSum) {        // ← capital 'S'
  this._useCheckSum = options.useCheckSum;
}

JavaScript property access is case-sensitive, so options.useCheckSum is undefined and _useCheckSum stays false.

Net effect

Guard Runs? Why
mtime check (useModifiedTimeValue && …) No Prettier sets useModifiedTime: false
size check (unconditional) Yes No guard in getFileDescriptor
hash check (useCheckSumValue && …) No _useCheckSum is false (bug)

Only file size is compared. Content hashing never runs.

History

This is a regression from the file-entry-cache v10 → v11 upgrade. In v10, the property was named useChecksum (lowercase), matching what Prettier passes. In v11, it was renamed to useCheckSum (capital S). Related: #17278 (the opposite problem in v10 — mtime checked when it shouldn't be).

Reproduction

# 1. Create a file and format it (populates cache)
echo '| A   | B   |' > test.md
echo '|---|---|' >> test.md
echo '| 1   | 2   |' >> test.md
prettier --write --cache --cache-strategy content test.md

# 2. Replace with different content of the SAME byte count
# (Prettier reformats |---| to | --- | — same length due to padding)
printf '| A   | B   |\n|---|---|\n| 1   | 2   |\n' > test.md

# 3. Cache falsely reports the file as clean
prettier --check --cache --cache-strategy content test.md
# ✅ "All matched files use Prettier code style!"  ← WRONG

# 4. Without cache, correctly detects the issue
prettier --check test.md
# ❌ "Code style issues found"                      ← CORRECT

A simpler reproduction using any two files with identical byte counts:

# Create two files with different content but same size (11 bytes each)
echo '0123456789' > a.txt    # 11 bytes
echo 'abcdefghij' > b.txt    # 11 bytes

# Cache a.txt as "formatted"
cp a.txt test.txt
prettier --write --cache --cache-strategy content test.txt

# Replace with b.txt (same size, different content)
cp b.txt test.txt

# Cache reports clean — only size was checked
prettier --check --cache --cache-strategy content test.txt
# "All matched files use Prettier code style!"

Suggested fix

One-character change — match the casing expected by file-entry-cache v11:

-    const useChecksum = cacheStrategy === "content";
+    const useCheckSum = cacheStrategy === "content";
     const fileEntryCacheOptions = {
-      useChecksum,
-      useModifiedTime: !useChecksum,
+      useCheckSum,
+      useModifiedTime: !useCheckSum,
       restrictAccessToCwd: false,
     };

Versions

  • Prettier: 3.8.1
  • file-entry-cache: 11.1.2 (bundled)
  • Node.js: 22.x
  • OS: macOS / Linux (reproducible on both)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions