Skip to content

Commit 7f6d8ef

Browse files
committed
fix(corpus): skip oversized files instead of aborting the whole build
Review found that returning bytelimit's error straight from collectFile made it fatal: collectFromRoot's WalkDir callback treats any error as abort-the-walk, and Collect returns on the first source error, so one big file discarded every record already collected from every source in the run. Stat the file first and skip it (matching the existing too-small-word/char-count skip pattern) instead of reading and failing; a real cloned repository can have one oversized file (a big CHANGELOG, a vendored spec) without that being reason to fail the whole corpus build. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UCh2j2oeSw6UgNsmpjRonL
1 parent 4d2c56e commit 7f6d8ef

2 files changed

Lines changed: 39 additions & 8 deletions

File tree

internal/corpus/collect.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,24 @@ func collectFile(
176176
return Record{}, false, nil
177177
}
178178

179+
// Skip files over the shared byte-limit cap rather than failing the
180+
// whole source: collectFromRoot's caller aborts the entire walk (and
181+
// every record already collected from every source before it, since
182+
// Collect returns on the first error) on any error from this
183+
// function. A cloned third-party repository can legitimately contain
184+
// one oversized file (a large CHANGELOG, a vendored spec) without
185+
// that file being reason to discard the rest of the corpus build.
186+
info, err := os.Stat(fullPath)
187+
if err != nil {
188+
return Record{}, false, fmt.Errorf("stat file %s: %w", fullPath, err)
189+
}
190+
if info.Size() > bytelimit.DefaultMaxInputBytes {
191+
reportProgress(cfg, fmt.Sprintf(
192+
"skipping %s: %d bytes exceeds the %d byte limit",
193+
relPath, info.Size(), bytelimit.DefaultMaxInputBytes))
194+
return Record{}, false, nil
195+
}
196+
179197
content, err := bytelimit.ReadFileLimited(fullPath, bytelimit.DefaultMaxInputBytes)
180198
if err != nil {
181199
return Record{}, false, fmt.Errorf("read file %s: %w", fullPath, err)

internal/corpus/collect_test.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -210,24 +210,31 @@ func TestCollect_ErrorPath(t *testing.T) {
210210
}
211211
}
212212

213-
// TestCollect_OversizedFile_ReturnsError guards against an unbounded
213+
// TestCollect_OversizedFile_SkippedNotFatal guards against an unbounded
214214
// os.ReadFile on a corpus source: collectFile ingests markdown from
215215
// cloned third-party repositories, which are untrusted input
216216
// (docs/development/high-performance-go.md — "os.ReadFile on huge
217217
// inputs: one giant alloc, all resident"). A file over the shared
218-
// bytelimit.DefaultMaxInputBytes cap must fail the walk rather than
219-
// being read into memory in full.
220-
func TestCollect_OversizedFile_ReturnsError(t *testing.T) {
218+
// bytelimit.DefaultMaxInputBytes cap must be skipped rather than read
219+
// into memory in full — and, since a real source repository can contain
220+
// one large file among many good ones (a big CHANGELOG, a vendored
221+
// spec), skipping it must not abort collection of the rest of that
222+
// source or of sources collected earlier in the same run.
223+
func TestCollect_OversizedFile_SkippedNotFatal(t *testing.T) {
221224
t.Parallel()
222225

223226
root := filepath.Join(t.TempDir(), "docs")
224227
if err := os.MkdirAll(root, 0o755); err != nil {
225228
t.Fatalf("mkdir: %v", err)
226229
}
227-
oversized := bytes.Repeat([]byte("a"), int(bytelimit.DefaultMaxInputBytes)+1)
230+
oversized := bytes.Repeat([]byte("a "), int(bytelimit.DefaultMaxInputBytes)/2+1)
228231
if err := os.WriteFile(filepath.Join(root, "huge.md"), oversized, 0o644); err != nil {
229232
t.Fatalf("write oversized markdown: %v", err)
230233
}
234+
normalContent := []byte("# Title\n\nword word word word word word\n")
235+
if err := os.WriteFile(filepath.Join(root, "normal.md"), normalContent, 0o644); err != nil {
236+
t.Fatalf("write normal markdown: %v", err)
237+
}
231238

232239
cfg := &Config{
233240
CollectedAt: "2026-02-16",
@@ -243,9 +250,15 @@ func TestCollect_OversizedFile_ReturnsError(t *testing.T) {
243250
}},
244251
}
245252

246-
_, err := Collect(cfg, t.TempDir())
247-
if err == nil {
248-
t.Fatal("Collect: expected an error for a file over the byte-limit cap, got nil")
253+
records, err := Collect(cfg, t.TempDir())
254+
if err != nil {
255+
t.Fatalf("Collect: unexpected error, oversized file should be skipped: %v", err)
256+
}
257+
if len(records) != 1 {
258+
t.Fatalf("record count = %d, want 1 (only normal.md; huge.md must be skipped)", len(records))
259+
}
260+
if records[0].Path != "normal.md" {
261+
t.Fatalf("Path = %q, want normal.md", records[0].Path)
249262
}
250263
}
251264

0 commit comments

Comments
 (0)