agalwood/Motrix · error · RangeError

samples[${index}].flags exceeds the SQLite bound

Error message

samples[${index}].flags exceeds the SQLite bound

What it means

`normalizeTransferSamples` validates each sample's `flags` via `assertNonNegativeSafeInteger` (so it is already a non-negative safe integer), then asserts it does not exceed `MAX_SAMPLE_FLAGS` = 2_147_483_647 (2^31-1). This matches the SQLite 32-bit INTEGER column used to store flags. The flag value is a bitmask of `TaskTransferSampleFlag` (1=status boundary, 2=terminal, 4=coverage gap), so realistic values are tiny.

Source

Thrown at src/core/inspector-activity/validators.ts:262

    case TaskHistoryEventKind.StageChanged:
      break
  }
}

export function normalizeTransferSamples(
  samples: readonly TaskTransferSample[]
): TaskTransferSample[] {
  return samples.map((sample, index) => ({
    t: assertPositiveSafeInteger(sample.t, `samples[${index}].t`),
    down: normalizeSpeed(sample.down, `samples[${index}].down`),
    up: normalizeSpeed(sample.up, `samples[${index}].up`),
    flags: (() => {
      const flags = assertNonNegativeSafeInteger(
        sample.flags,
        `samples[${index}].flags`
      )
      if (flags > MAX_SAMPLE_FLAGS) {
        throw new RangeError(`samples[${index}].flags exceeds the SQLite bound`)
      }
      return flags
    })(),
  }))
}

export function validateCheckpoint(
  input: TaskActivityCheckpoint
): TaskActivityCheckpoint {
  const taskId = assertTaskId(input.taskId)
  assertPositiveSafeInteger(input.updatedAt, 'updatedAt')
  assertNonNegativeSafeInteger(input.activeMsDelta, 'activeMsDelta')
  assertNonNegativeSafeInteger(
    input.downloadActiveMsDelta,
    'downloadActiveMsDelta'
  )
  assertNonNegativeBigInt(
    input.estimatedDownloadBytesDelta,

View on GitHub (pinned to 1a708ee577)

Solutions

  1. Ensure `flags` is built only by OR-ing members of `TaskTransferSampleFlag` (1, 2, 4).
  2. Default missing flags to 0, not to a sentinel.
  3. If a non-bitmask integer must accompany the sample, add a new field rather than overloading flags.

Example fix

// before
sample.flags = peerCount  // peerCount can exceed 2^31-1
// after
sample.flags = isBoundary ? TaskTransferSampleFlag.StatusBoundary : 0
Defensive patterns

Strategy: validation

Validate before calling

import { TaskTransferSampleFlag } from '@shared/types/task-inspector-activity'
function composeFlags(parts: TaskTransferSampleFlag[]): number {
  return parts.reduce((acc, f) => acc | f, 0)
}

Type guard

import { MAX_SAMPLE_FLAGS } from '@core/inspector-activity/validators'
function isSampleFlags(v: unknown): boolean {
  return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0 && v <= MAX_SAMPLE_FLAGS
}

Prevention

When it happens

Trigger: A sample whose `flags` field carries a large number — typically a numeric status code or peer count mistakenly written into the bitmask, or an aggregator that OR-ed in a non-flag value.

Common situations: Producer code that reuses the `flags` field for an unrelated integer; tests that hand-craft samples with random numbers; deserialization that defaulted a missing flags to a sentinel like `0xFFFFFFFF`.

Related errors


AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12). Data as JSON: /api/errors/be122dc6f4619cbf. Report an issue: GitHub.