sinelaw/fresh · warning
Tour: could not resolve lines
Error message
Tour: could not resolve lines ${step.lines[0]}-${step.lines[1]} in ${step.file_path} What it means
In the code-tour plugin, paintStepOverlay resolves the step's target file to a buffer and asks the host for the byte range covering step.lines[0]..step.lines[1]; if lineRangeBytes returns null the lines cannot be resolved (file shorter than requested, or buffer content changed) and this warning is emitted instead of painting the overlay. The tour step is skipped visually but the tour continues.
Solutions
- Update the step's lines to a range that exists in the current version of step.file_path.
- Verify step.file_path resolves correctly relative to the tour manifest (resolveStepPath).
- Re-generate the tour against the current commit, or pin the tour to a matching revision of the target file.
- Open the target file and confirm its line count covers lines[0]-lines[1].
Example fix
// before (tour step)
{ "file_path": "src/app.ts", "lines": [120, 140] } // file has 100 lines
// after
{ "file_path": "src/app.ts", "lines": [10, 24] } Defensive patterns
Strategy: validation
Validate before calling
const content = fs.readFileSync(resolveStepPath(manifestPath, step.file_path), 'utf8');
const lineCount = content.split('\n').length;
if (step.lines[0] < 1 || step.lines[1] >= lineCount) {
throw new Error(`step lines ${step.lines[0]}-${step.lines[1]} exceed ${step.file_path} (${lineCount} lines)`);
} Type guard
function linesInRange(step, totalLines) { return Array.isArray(step.lines) && step.lines.length === 2 && step.lines[0] >= 1 && step.lines[1] < totalLines; } Try / catch
try { await revealStep(tour, i); } catch (e) { if (e.message.includes('could not resolve lines')) editor.warn(`skipping step ${i}: target moved`); else throw e; } Prevention
- Regenerate tours whenever the target files change; avoid hand-editing line numbers.
- Use anchors/symbols instead of raw line numbers when authoring tours.
- Validate all step line ranges against the current tree in CI.
- Keep tour manifests in the same repo/commit as their target files.
When it happens
Trigger: revealStep -> paintStepOverlay on a step whose lines[0]/lines[1] exceed the target buffer's current line count, the target file's buffer could not load those lines, or the file was edited/truncated since the tour was authored.
Common situations: Sharing a tour whose target file differs between machines (different branch/commit); target file refactored so highlighted lines no longer exist; typos in the step's file_path or 1-based line numbers past EOF.
Related errors
- [pkg] Failed to update registry
- [pkg] Failed to clone registry
- [pkg] Invalid package
- [pkg] Bundle plugin not found
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/6328bdd25f4005c6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor/plugins/code-tour.ts:600
return 0;
}
function clearTourOverlays(t: TourInstance): void {
for (const bufferId of t.paintedBuffers) {
editor.clearNamespace(bufferId, t.namespace);
}
t.paintedBuffers.clear();
}
async function paintStepOverlay(t: TourInstance): Promise<void> {
const step = currentStep(t);
const bufferId = stepBufferId(resolveStepPath(t.manifestPath, step.file_path));
if (!bufferId) return;
clearTourOverlays(t);
const range = await lineRangeBytes(bufferId, step.lines[0], step.lines[1]);
if (!range) {
editor.warn(
`Tour: could not resolve lines ${step.lines[0]}-${step.lines[1]} in ${step.file_path}`,
);
return;
}
// One range-wide overlay; the host tail-fills every row it spans, so
// each line paints a full-width band — a region marker visually
// distinct from a text selection (which never covers the empty tail
// of a line). The bg is a theme key so the band restyles with the
// theme, like every other tour colour. It is the band's *own* key:
// the occurrence highlight next door is tuned for a few cells of text
// that must stay legible and stay apart from the selection, which is
// the wrong trade for a wash over whole line ranges.
editor.addOverlay(bufferId, t.namespace, range[0], range[1], {
bg: "ui.tour_step_bg",
extendToLineEnd: true,
});
t.paintedBuffers.add(bufferId);
}View on GitHub (pinned to 67894ca546)