FuelLabs/fuels-ts · error · FuelError

INVALID_DATA

INVALID_DATA

Error message

cannot slice beyond data bounds

What it means

Thrown by dataSlice when an explicit end offset is greater than the length of the underlying byte array (after arrayify converts the input). Only the upper bound is validated; a start beyond length is not checked here (it would just yield an empty slice). Protects callers from reading past the end of the data buffer.

Source

Thrown at packages/utils/src/utils/dataSlice.ts:18

import { ErrorCode, FuelError } from '@fuel-ts/errors';

import { arrayify } from './arrayify';
import type { BytesLike } from './arrayify';
import { hexlify } from './hexlify';

/**
 *  Returns a hex string by slicing data from the start offset to the end offset.
 *
 * @param data - the data to be sliced.
 * @param start - the start offset (default: 0).
 * @param end - the end offset (default: length of data).
 * @returns - a sliced hex string from start to end.
 */
export function dataSlice(data: BytesLike, start?: number, end?: number): string {
  const bytes = arrayify(data);
  if (end != null && end > bytes.length) {
    throw new FuelError(ErrorCode.INVALID_DATA, 'cannot slice beyond data bounds');
  }
  return hexlify(bytes.slice(start == null ? 0 : start, end == null ? bytes.length : end));
}

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Check the actual byte length before slicing and clamp end to bytes.length.
  2. Compute end from the real data length rather than a hardcoded constant.
  3. Pad short values to the expected size before slicing if a fixed-width read is required.
  4. Use arrayify first to learn the length, then derive a safe end.

Example fix

// before
dataSlice('0x1234', 0, 32); // throws: only 2 bytes

// after
const bytes = arrayify('0x1234');
const end = Math.min(32, bytes.length);
dataSlice(bytes, 0, end);
Defensive patterns

Strategy: validation

Validate before calling

import { arrayify } from '@fuel-ts/utils';
function safeSlice(data: BytesLike, start = 0, end?: number) {
  const len = arrayify(data).length;
  const e = end == null ? len : Math.min(end, len);
  if (start > len) start = len;
  return dataSlice(data, start, e);
}

Try / catch

try {
  const hex = dataSlice(data, start, end);
} catch (e) {
  if (e instanceof FuelError && e.code === ErrorCode.INVALID_DATA) {
    // clamp end to actual length and retry, or report short payload
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling dataSlice(data, start, end) with end > bytes.length. For example dataSlice('0x1234', 0, 4) when only 2 bytes exist, or dataSlice(shortBytes, 0, 32) expecting a 32-byte word from a shorter value.

Common situations: Assuming a fixed-size (e.g. 32-byte) value when the input is shorter. Off-by-one in offset math. Slicing a partially-received or truncated payload. Hardcoding end=32 for b256-sized reads on a value that has fewer bytes.

Related errors


AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12). Data as JSON: /api/errors/48df8a2f0d34c43f. Report an issue: GitHub.