BabylonJS/Babylon.js · error

${context}: unexpected end of input

Error message

${context}: unexpected end of input

What it means

ensureRange is the FBX binary parser's bounds check: it verifies that reading byteLength bytes at offset stays within the parse limit and the input buffer. If not, it throws '<context>: unexpected end of input', where context names which parse step (parseNode/parseProperty/parseArrayProperty) ran past the available bytes.

Source

Thrown at packages/dev/loaders/src/FBX/parsers/fbxBinaryParser.ts:256

        case "boolean[]":
            value = arrayData;
            break;
        case "int64[]":
            value = readInt64ArrayData(arrayData);
            break;
        default:
            throw new Error(`Unexpected array type: ${type}`);
    }

    return {
        property: { type, value },
        nextOffset: offset + compressedLength,
    };
}

function ensureRange(bytes: Uint8Array, offset: number, byteLength: number, limit: number, context: string): void {
    if (offset < 0 || byteLength < 0 || offset + byteLength > limit || offset + byteLength > bytes.byteLength) {
        throw new Error(`${context}: unexpected end of input`);
    }
}

function readUint64AsNumber(view: DataView, offset: number): number {
    const low = view.getUint32(offset, true);
    const high = view.getUint32(offset + 4, true);
    return high * 0x100000000 + low;
}

function readInt64AsNumber(view: DataView, offset: number): number {
    const low = view.getUint32(offset, true);
    const high = view.getInt32(offset + 4, true);
    return high * 0x100000000 + low;
}

function readInt64ArrayData(arrayData: Uint8Array): Float64Array {
    const view = new DataView(arrayData.buffer, arrayData.byteOffset, arrayData.byteLength);
    const values = new Float64Array(arrayData.byteLength / 8);

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Verify the file is fully downloaded (size/hash check) and re-download if truncated
  2. Check that any byte offset/limit you pass into the parser points at the real start of the FBX binary section
  3. Validate the file with a reference FBX reader; if it fails there too, the file is corrupt — re-export it
  4. If parsing embedded FBX blobs, confirm the container's length field is correct
  5. Wrap parsing in try-catch and surface a user-facing 'corrupt or incomplete FBX file' message

Example fix

// before
const bytes = fs.readFileSync(partialPath); parse(bytes);
// after
if (actualHash !== expectedHash) throw new Error('FBX download incomplete; re-fetching');
const bytes = fs.readFileSync(fullyDownloadedPath); parse(bytes);
Defensive patterns

Strategy: validation

Validate before calling

// caller-side check before parsing
if (bytes.byteLength < MIN_FBX_HEADER_LENGTH || bytes.byteLength < declaredFileSize) {
  throw new Error('FBX file truncated or empty');
}

Type guard

function hasSufficientBytes(bytes: Uint8Array, offset: number, need: number): boolean {
  return offset >= 0 && offset + need <= bytes.byteLength;
}

Try / catch

try {
  scene = parseFbxBinary(bytes);
} catch (e) {
  if ((e as Error).message.endsWith('unexpected end of input')) {
    throw new Error('FBX file is incomplete or corrupted — re-download it', { cause: e });
  }
  throw e;
}

Prevention

When it happens

Trigger: Any nested record whose declared length or offset reaches past bytes.byteLength or the parent node limit: a truncated file, a node header advertising more bytes than exist, or an offset computed from a bad earlier field landing beyond the buffer.

Common situations: Incomplete downloads of .fbx files; files cut off mid-write; corrupt container unzips; a progress/limit parameter passed incorrectly when parsing a sub-region; reading an FBX embedded inside another file with wrong offsets.

Understand the failure class

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/e7f73f03f802b0a5. Report an issue: GitHub.