phacility/phabricator · error · Exception
Unable to find fetch!
Error message
Unable to find fetch!
What it means
Thrown by the build-log rendering controller after it computes the byte-range reads (head window, tail window, highlight ranges) it will fetch. Each read produces a [fetchOffset, fetchOffset+fetchLength] window clamped to the current log size; this exception means the view's anchor byte (the requested offset, minus 1 for tail views) does not fall inside any computed window. It is an internal invariant failure: the offset the caller asked for no longer lies in the data that was actually read, almost always because the log's length changed between the request parameters being generated and the data being fetched.
Source
Thrown at src/applications/harbormaster/controller/HarbormasterBuildLogRenderController.php:172
$anchor_byte = $view['offset'];
if ($view['direction'] < 0) {
$anchor_byte = $anchor_byte - 1;
}
$data_key = null;
foreach ($reads as $read_key => $read) {
$s = $read['fetchOffset'];
$e = $s + $read['fetchLength'];
if (($s <= $anchor_byte) && ($e >= $anchor_byte)) {
$data_key = $read_key;
break;
}
}
if ($data_key === null) {
throw new Exception(
pht('Unable to find fetch!'));
}
$anchor_key = null;
foreach ($reads[$data_key]['lines'] as $line_key => $line) {
$s = $line['offset'];
$e = $s + $line['length'];
if (($s <= $anchor_byte) && ($e > $anchor_byte)) {
$anchor_key = $line_key;
break;
}
}
if ($anchor_key === null) {
throw new Exception(
pht(
'Unable to find lines.'));View on GitHub (pinned to 5720a38cfe)
Solutions
- Reload the log page without the offset parameters (fresh /log/... URL) so offsets are recomputed from the current log size.
- If it recurs for a specific log, compare the log's recorded byte length with the sum of its stored chunks (harbormaster_buildlogchunk) to detect corruption or a half-finished archival.
- If you maintain this code, clamp anchor_byte to [0, log_size-1] (and skip views whose window is empty) instead of throwing, so stale offsets degrade gracefully.
- For scrapers, fetch the log metadata/current size before requesting byte ranges, and re-derive offsets each run.
Example fix
// before (HarbormasterBuildLogRenderController.php)
$anchor_byte = $view['offset'];
if ($view['direction'] < 0) {
$anchor_byte = $anchor_byte - 1;
}
// ...
if ($data_key === null) {
throw new Exception(pht('Unable to find fetch!'));
}
// after
$anchor_byte = $view['offset'];
if ($view['direction'] < 0) {
$anchor_byte = $anchor_byte - 1;
}
$anchor_byte = min(max(0, $anchor_byte), max(0, $log_size - 1));
// ...window search now always succeeds for nonempty logs Defensive patterns
Strategy: validation
Validate before calling
// Before requesting a log render with offsets, re-check them against the
// log's current size (HarbormasterBuildLogQuery + getTotalByteLength equivalent):
$size = get_log_byte_length($log); // e.g. via the log's getSize() / chunk sum
$head_offset = min(max(0, $head_offset), $size);
$tail_offset = min(max(0, $tail_offset), $size);
if ($highlight_range) { $highlight_range = clamp_range($highlight_range, 0, $size); } Try / catch
try {
renderLogViews($log, $views);
} catch (Exception $e) {
// Stale offsets: fall back to a fresh, offset-free render
return renderLogViews($log, defaultViews($log));
} Prevention
- Always re-derive head/tail offsets from the log's current byte length instead of reusing cached URLs or offsets.
- When scraping render endpoints, fetch log metadata first and clamp all range parameters to [0, size].
- Treat log size as volatile during active builds and archival; retry once with fresh parameters before surfacing an error.
When it happens
Trigger: Opening /harbormaster/log/... with stale headOffset/tailOffset or a 'lines' highlight range that lies beyond the log's current byte length: the log was truncated, rotated, or archived/compressed (changing its size) since the page or URL was produced; or a scraper/script replays a render URL with hard-coded offsets after the build log grew or shrank. Also possible when log chunk data is corrupted so the readable data is shorter than the recorded log size.
Common situations: A build log page left open in a browser while the daemon archives/compresses the log; log garbage collection shortening a log; automated tools hitting the render endpoint with saved offsets; database chunk corruption after a partial migration.
Related errors
- Unable to find lines.
- Choose a build log to rebuild with "--id", or rebuild all lo
- You can not specify both "--id" and "--all". Choose one or t
- Unable to load build log "%s".
- Choose a build target to attach the log to with "--target".
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/03620c3d08f16ab3.
Report an issue: GitHub.