ruvnet/ruflo · error
Sections " " and " " overlap ( + > )
Error message
Sections "${prev.id}" and "${curr.id}" overlap (${prev.offset}+${prev.size} > ${curr.offset}) What it means
After sorting header.sections by offset, a section's declared range [offset, offset+size) intrudes into the next section's range (prev.offset + prev.size > curr.offset). The writer always lays out sections contiguously, so any overlap means the header was hand-edited, corrupted, or crafted so extraction reads bytes belonging to a different section — a consistency check, not a size check.
Solutions
- Rebuild the image with RvfaWriter — it recomputes all offsets contiguously in build(), which cannot overlap by construction
- If patching is required, recompute every subsequent section's offset after resizing any section, then rewrite the footer hash
- For untrusted images, verify the detached signature before parsing — overlapping sections on a signed file also indicates signature/content mismatch
- Extract header.sections, sort by offset, and assert gaps are exactly size-aligned before distributing the image
Example fix
// before — patched section size without shifting the next offset
sections[0].size += 256; // now overlaps sections[1]
// after — shift every following section and fix the image
let cursor = sections[0].offset;
for (const s of sections.sort((a, b) => a.offset - b.offset)) {
s.offset = cursor;
cursor += s.size;
} Defensive patterns
Strategy: validation
Validate before calling
const sections = [...header.sections].sort((a, b) => a.offset - b.offset);
for (let i = 1; i < sections.length; i++) {
if (sections[i - 1].offset + sections[i - 1].size > sections[i].offset)
throw new Error('section table inconsistent — rebuild image');
} Try / catch
try { reader = RvfaReader.fromBuffer(buf); }
catch (e) {
if (/overlap/.test(String((e as Error).message))) {
// header was patched/corrupted: rebuild with RvfaWriter
}
throw e;
} Prevention
- Never patch one section's size in place without shifting subsequent offsets
- Always rebuild through RvfaWriter when section contents change
- Verify signatures before parsing third-party images
When it happens
Trigger: RvfaReader.fromBuffer where two header.sections[] entries reference intersecting byte ranges — e.g. offsets manually adjusted after image rebuild, a header JSON edited to point a section at another's data, or fuzzed/corrupt headers with scrambled offsets.
Common situations: Hand-patching a header to swap or inline a section; tools that rewrite one section in-place and forget to shift later offsets; malicious images trying to alias section data; copy-paste errors in custom build scripts that duplicate a descriptor with a stale offset.
Related errors
- Section " " has negative offset or size
- Buffer too small to contain declared header
- Buffer too small to contain RVFA preamble
- Failed to parse RVFA header JSON
- Invalid RVFA magic: expected "RVFA", got
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/e8fb9ceb657e0cba.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/appliance/rvfa-format.ts:374
for (const sec of header.sections) {
if (sec.offset < 0 || sec.size < 0) {
throw new Error(`Section "${sec.id}" has negative offset or size`);
}
if (sec.offset + sec.size > totalSize - SHA256_SIZE) {
throw new Error(
`Section "${sec.id}" extends beyond buffer ` +
`(offset=${sec.offset}, size=${sec.size}, bufLen=${totalSize})`,
);
}
}
// Check for overlapping sections
const sorted = [...header.sections].sort((a, b) => a.offset - b.offset);
for (let i = 1; i < sorted.length; i++) {
const prev = sorted[i - 1];
const curr = sorted[i];
if (prev.offset + prev.size > curr.offset) {
throw new Error(
`Sections "${prev.id}" and "${curr.id}" overlap ` +
`(${prev.offset}+${prev.size} > ${curr.offset})`,
);
}
}
return new RvfaReader(buf, header);
}
/** Read an RVFA image from a file path. */
static async fromFile(path: string): Promise<RvfaReader> {
if (path.includes('\0')) {
throw new Error('Path contains null bytes');
}
const data = await readFile(path);
return RvfaReader.fromBuffer(data);
}
View on GitHub (pinned to fa13ee4ad6)