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

  1. Rebuild the image with RvfaWriter — it recomputes all offsets contiguously in build(), which cannot overlap by construction
  2. If patching is required, recompute every subsequent section's offset after resizing any section, then rewrite the footer hash
  3. For untrusted images, verify the detached signature before parsing — overlapping sections on a signed file also indicates signature/content mismatch
  4. 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

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


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)