agalwood/Motrix · error · RangeError

${label} must contain between 1 and ${maxLength} characters

Error message

${label} must contain between 1 and ${maxLength} characters

What it means

`assertBoundedText` accepts either `null` (treated as absent/ok) or a non-empty string no longer than `maxLength`. It throws this `RangeError` if the value is not a string, is an empty string, or exceeds `maxLength`. The `label` and `maxLength` come from the caller — `eventKey`/`runtimeGeneration` (256), `errorCode` (128), `errorMessage` (2048), `errorDetailKey` (128). The bounds mirror the SQLite TEXT column widths so inserts never truncate.

Source

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

  assertNonNegativeSafeInteger(delta, 'delta')
  if (delta > MAX_SAFE_SQLITE_INTEGER - current) {
    return { value: MAX_SAFE_SQLITE_INTEGER, saturated: true }
  }
  return { value: current + delta, saturated: false }
}

function assertBoundedText(
  value: string | null,
  label: string,
  maxLength: number
): void {
  if (value === null) return
  if (
    typeof value !== 'string' ||
    value.length === 0 ||
    value.length > maxLength
  ) {
    throw new RangeError(
      `${label} must contain between 1 and ${maxLength} characters`
    )
  }
}

function assertStatus(value: TaskStatus | null, label: string): void {
  if (value !== null && !STATUS_VALUES.has(value)) {
    throw new RangeError(`${label} is not a legal task status`)
  }
}

function assertBoundedDetailParams(
  value: Record<string, string> | null,
  label: string,
  maxJsonLength: number
): void {
  if (value === null) return
  if (

View on GitHub (pinned to 1a708ee577)

Solutions

  1. Replace empty strings with `null` for absent fields — the validator explicitly allows null.
  2. Truncate long values before submission: `value.slice(0, maxLength)` (after confirming the loss is acceptable).
  3. Check the field's intended unit — `errorCode` is a short code, `errorMessage` a one-liner; full payloads belong elsewhere.
  4. Wire the producer to the same exported `MAX_*_LENGTH` constants so truncation happens once at the edge.

Example fix

// before
event.errorMessage = err.message  // may be '' or 5KB
// after
event.errorMessage = err.message ? err.message.slice(0, 2048) : null
Defensive patterns

Strategy: validation

Validate before calling

function boundText(value: string | null, max: number): string | null {
  if (value === null || value.length === 0) return null
  return value.slice(0, max)
}

Type guard

function isBoundedText(v: unknown, max: number): v is string | null {
  return v === null || (typeof v === 'string' && v.length > 0 && v.length <= max)
}

Prevention

When it happens

Trigger: Submitting a `TaskHistoryEventInput` where a bounded text field is `''` (empty string instead of `null`), an over-long string, or accidentally typed as `undefined`/number. For example, an event with `errorMessage: ''` after a successful retry, or an `errorCode` longer than 128 chars from a verbose engine response.

Common situations: Tests using empty strings as placeholders instead of `null`; logging a full stack trace into `errorMessage`; an engine that returns a multi-kilobyte error body; copy-pasting a long URL into `errorDetailKey`.

Related errors


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