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

  1. Reload the log page without the offset parameters (fresh /log/... URL) so offsets are recomputed from the current log size.
  2. 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.
  3. 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.
  4. 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

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


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/03620c3d08f16ab3. Report an issue: GitHub.