{"record":{"id":"be122dc6f4619cbf","repo":"agalwood/Motrix","slug":"samples-index-flags-exceeds-the-sqlite-bound","errorCode":null,"errorMessage":"samples[${index}].flags exceeds the SQLite bound","messagePattern":"samples\\[(.+?)\\]\\.flags exceeds the SQLite bound","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"src/core/inspector-activity/validators.ts","lineNumber":262,"sourceCode":"    case TaskHistoryEventKind.StageChanged:\n      break\n  }\n}\n\nexport function normalizeTransferSamples(\n  samples: readonly TaskTransferSample[]\n): TaskTransferSample[] {\n  return samples.map((sample, index) => ({\n    t: assertPositiveSafeInteger(sample.t, `samples[${index}].t`),\n    down: normalizeSpeed(sample.down, `samples[${index}].down`),\n    up: normalizeSpeed(sample.up, `samples[${index}].up`),\n    flags: (() => {\n      const flags = assertNonNegativeSafeInteger(\n        sample.flags,\n        `samples[${index}].flags`\n      )\n      if (flags > MAX_SAMPLE_FLAGS) {\n        throw new RangeError(`samples[${index}].flags exceeds the SQLite bound`)\n      }\n      return flags\n    })(),\n  }))\n}\n\nexport function validateCheckpoint(\n  input: TaskActivityCheckpoint\n): TaskActivityCheckpoint {\n  const taskId = assertTaskId(input.taskId)\n  assertPositiveSafeInteger(input.updatedAt, 'updatedAt')\n  assertNonNegativeSafeInteger(input.activeMsDelta, 'activeMsDelta')\n  assertNonNegativeSafeInteger(\n    input.downloadActiveMsDelta,\n    'downloadActiveMsDelta'\n  )\n  assertNonNegativeBigInt(\n    input.estimatedDownloadBytesDelta,","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/inspector-activity/validators.ts#L244-L280","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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`.","solutions":["Ensure `flags` is built only by OR-ing members of `TaskTransferSampleFlag` (1, 2, 4).","Default missing flags to 0, not to a sentinel.","If a non-bitmask integer must accompany the sample, add a new field rather than overloading flags."],"exampleFix":"// before\nsample.flags = peerCount  // peerCount can exceed 2^31-1\n// after\nsample.flags = isBoundary ? TaskTransferSampleFlag.StatusBoundary : 0","handlingStrategy":"validation","validationCode":"import { TaskTransferSampleFlag } from '@shared/types/task-inspector-activity'\nfunction composeFlags(parts: TaskTransferSampleFlag[]): number {\n  return parts.reduce((acc, f) => acc | f, 0)\n}","typeGuard":"import { MAX_SAMPLE_FLAGS } from '@core/inspector-activity/validators'\nfunction isSampleFlags(v: unknown): boolean {\n  return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0 && v <= MAX_SAMPLE_FLAGS\n}","tryCatchPattern":null,"preventionTips":["Treat `flags` strictly as a bitmask of `TaskTransferSampleFlag`.","Default to 0, never to a sentinel.","Keep peer counts and status codes in dedicated fields."],"tags":["validation","range-error","bitmask","sqlite"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}