can1357/oh-my-pi · error
Offset #{start_line} is beyond end of output (#{total_lines}
Error message
Offset #{start_line} is beyond end of output (#{total_lines} lines) for #{output_id} What it means
When `output` is called with `offset` (and/or `limit`), the artifact is paged by lines. The offset is clamped to a minimum of 1, but if the requested start line exceeds the artifact's total line count there is nothing to return, so the prelude raises with the requested start line, the total lines, and the output ID.
Source
Thrown at packages/coding-agent/src/eval/rb/prelude.rb:221
json_value =
begin
JSON.parse(raw)
rescue JSON::ParserError => e
__omp_emit_status("output", "id" => output_id, "error" => "Not valid JSON: #{e.message}")
raise "Output #{output_id} is not valid JSON: #{e.message}"
end
result_value = __omp_apply_query(json_value, query)
selected =
begin
result_value.nil? ? "null" : JSON.pretty_generate(result_value)
rescue StandardError
result_value.to_s
end
elsif !offset.nil? || !limit.nil?
start_line = [offset || 1, 1].max
if start_line > total_lines
__omp_emit_status("output", "id" => output_id, "error" => "Offset #{start_line} beyond end (#{total_lines} lines)")
raise "Offset #{start_line} is beyond end of output (#{total_lines} lines) for #{output_id}"
end
effective_limit = limit || (total_lines - start_line + 1)
end_line = [total_lines, start_line + effective_limit - 1].min
selected = raw_lines[(start_line - 1)...end_line].join("\n")
range_info = { "start_line" => start_line, "end_line" => end_line, "total_lines" => total_lines }
end
selected = selected.gsub(/\e\[[0-9;]*m/, "") if format == "stripped"
if format == "json"
entry = {
"id" => output_id,
"path" => path,
"line_count" => query ? selected.split("\n").length : total_lines,
"char_count" => query ? selected.length : raw.length,
"content" => selected,
}
entry["range"] = range_info if range_infoView on GitHub (pinned to 9690622007)
Solutions
- Use a smaller offset within the artifact's actual length (the error message states total_lines).
- Detect the end of paging: catch the error and stop paginating, or first read without offset and count lines.
- If you need to know the size up front, fetch `format: 'json'` and use the returned `line_count` before computing the next offset.
Example fix
// before
chunk = output('log', offset: 500, limit: 100) # file only has 120 lines
// after
info = output('log', format: 'json')
chunk = info['line_count'] >= 500 ? output('log', offset: 500, limit: 100) : nil Defensive patterns
Strategy: validation
Validate before calling
info = output(id, format: 'json') total = info['line_count'] raise RangeError, 'offset past end' if offset > total
Try / catch
begin chunk = output(id, offset: next_offset, limit: page_size) rescue RuntimeError => e raise unless e.message =~ /beyond end of output/ chunk = nil # reached end of artifact end
Prevention
- Stop paginating when a returned page is shorter than the requested limit instead of issuing one more page.
- Fetch line_count via format: 'json' before computing offsets.
- Clamp offset to [1, total_lines] before calling.
When it happens
Trigger: Calling `output('<id>', offset: N)` (or `offset: N, limit: M`) where the `<id>.md` artifact has fewer than N lines — e.g. a 3-line log fetched with `offset: 10`, or a stale cached line count reused after the artifact was regenerated shorter.
Common situations: Paging through an artifact with a fixed page size and running past the end; re-running a paging script after the artifact shrank; off-by-one assumptions that offset is zero-based (clamped to 1 here).
Related errors
- query cannot be combined with offset/limit
- Output #{output_id} is not valid JSON: #{e.message}
- tool bridge is unavailable in this kernel
- parallel() expects an iterable of zero-arg callables
- pipeline() stages must be callables
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/0e3f914d8baeae16.
Report an issue: GitHub.