Skip to content

push_repo_memory: pre-check measures total content, push gate measures diff additions — same config knob, mismatched semantics + misleading error #42773

Description

@nestele

Summary

push_repo_memory has two size checks that share the same max-patch-size config value but measure fundamentally different things, and the error message from one of them is misleading about what it actually measured.

Related to (but distinct from) #22281, which fixed the pre-check to sum current file sizes instead of unbounded diff history. This issue is about the remaining inconsistency between the two checks that exist post-fix.

The two checks

  1. MCP push_repo_memory tool pre-check (actions/setup/js/safe_outputs_handlers.cjs), runs during the agent job before anything is committed:

    const totalSize = files.reduce((sum, f) => sum + f.size, 0);
    ...
    if (totalSize > effectiveMaxPatchSize) { ... }

    This sums the raw byte size of every file currently in the memory directory (recursively, .git excluded) — i.e. the whole tree, not a diff.

  2. Push job gate (actions/setup/js/push_repo_memory.cjs), the actual persistence step, runs if: always():

    const patchContent = execGitSync(["diff", "--cached"], ...);
    const addedSizeBytes = patchContent
      .split("\n")
      .filter(line => line.startsWith("+") && !line.startsWith("+++"))
      .reduce((sum, line) => sum + Buffer.byteLength(line + "\n", "utf8"), 0);

    This counts only added lines in git diff --cached for this run's commit.

Both are gated by the same max-patch-size (default 10 KB, effective 12 KB with the 20% overhead multiplier), but they answer different questions: "how big is the whole memory tree" vs. "how much did this run add."

Impact

A workflow with a modest but accumulated memory tree (e.g. static task-definition files plus per-run history records) can be permanently blocked by check #1 even though check #2 — the real gate — would pass every time, because the actual per-run diff is tiny. The agent has no way to satisfy "keep total content under X" and "allow generous per-run diffs" independently; both are the same knob.

We observed this in production: a workflow with ~21 KB of accumulated memory files (task definitions + run-history JSON) was rejected by check #1 with:

Total memory size (21 KB) exceeds the allowed limit of 12 KB
(configured limit: 10 KB with 20% overhead for git diff format).

even though the actual patch for that run was a few hundred bytes.

The misleading error message

The rejection text from check #1 says:

"...allowed limit of 12 KB (configured limit: 10 KB with 20% overhead for git diff format)"

This phrasing (and the accompanying code comment "mirrors the same calculation in push_repo_memory.cjs") implies a git diff was computed and 20% overhead was added for diff formatting (headers, @@ hunks, context lines). In reality, check #1 never runs git diff — it sums raw file sizes. The "20% overhead for git diff format" justification, and the "mirrors" comment, are copy-pasted from check #2's real diff-based logic and don't apply here. This makes the error confusing to debug (you go looking for oversized diffs when the real issue is total tree size).

Suggested fix

Pick one:

  • A. Decouple the two checks into separate config knobs (e.g. max-content-size for the pre-check, max-patch-size for the real diff gate), so workflows can allow a larger total memory footprint while still keeping individual push diffs small (or vice versa).
  • B. Make the pre-check diff-aware too (e.g. have it stage the changes and measure git diff --cached added lines, matching check Add workflow: githubnext/agentics/weekly-research #2 exactly), so both checks agree and the shared config value has one consistent meaning.
  • At minimum: fix the error message on check rejig docs #1 to describe what it actually measured (total file bytes in the directory), and drop the inaccurate "20% overhead for git diff format" / "mirrors the same calculation" framing for that specific check.

Environment

  • gh-aw version: v0.81.6 (workflow compiled with gh aw compile)
  • repo-memory config: max-patch-size default (10240 bytes)

Metadata

Metadata

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions