remotion-dev/remotion · error · TypeError
"samples" must be >= 1, but got ${samples}
Error message
"samples" must be >= 1, but got ${samples} What it means
Thrown by @remotion/effects' lightTrail effect when the optional `samples` param resolves to a non-positive integer. After `?? DEFAULT_SAMPLES` (32), `validateSamples` first checks integer-ness, then rejects any value below 1. `samples` controls how many directional taps the trail shader uses to approximate the motion blur streak.
Source
Thrown at packages/effects/src/light-trail/index.ts:133
};
const resolve = (p: LightTrailParams): LightTrailResolved => ({
direction: p.direction ?? DEFAULT_DIRECTION,
distance: p.distance ?? DEFAULT_DISTANCE,
intensity: p.intensity ?? DEFAULT_INTENSITY,
decay: p.decay ?? DEFAULT_DECAY,
threshold: p.threshold ?? DEFAULT_THRESHOLD,
samples: p.samples ?? DEFAULT_SAMPLES,
color: p.color ?? DEFAULT_COLOR,
});
const validateSamples = (samples: number): void => {
if (!Number.isInteger(samples)) {
throw new TypeError(`"samples" must be an integer, but got ${samples}`);
}
if (samples < 1) {
throw new TypeError(`"samples" must be >= 1, but got ${samples}`);
}
if (samples > MAX_SAMPLES) {
throw new TypeError(
`"samples" must be <= ${MAX_SAMPLES}, but got ${samples}`,
);
}
};
const validateLightTrailParams = (params: LightTrailParams): void => {
assertEffectParamsObject(params, 'Light trail');
assertOptionalFiniteNumber(params.direction, 'direction');
assertOptionalFiniteNumber(params.distance, 'distance');
assertOptionalFiniteNumber(params.intensity, 'intensity');
assertOptionalFiniteNumber(params.decay, 'decay');
assertOptionalFiniteNumber(params.threshold, 'threshold');
assertOptionalFiniteNumber(params.samples, 'samples');
assertOptionalColor(params.color, 'color');View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Use `samples: Math.max(1, Math.round(value))` (or omit the prop to get the default 32) before passing it in.
- If driving `samples` from an interpolated/integrated value, clamp the lower bound to 1 in the interpolation config.
- Treat 0 or negative as 'unset' and conditionally spread the prop: `...(v > 0 ? {samples: v} : {})`.
- Audit any shared config object reused across effects for a `samples` field that another effect permits as 0.
Example fix
// before
lightTrail({ samples: frame >= 10 ? samplesForFrame(frame) : 0 });
// after
const raw = frame >= 10 ? samplesForFrame(frame) : 1;
lightTrail({ samples: Math.max(1, Math.round(raw)) }); Defensive patterns
Strategy: validation
Validate before calling
const safeSamples = (v: unknown): number => {
if (v === undefined || v === null) return 32; // DEFAULT_SAMPLES
if (typeof v !== 'number' || !Number.isFinite(v)) {
throw new TypeError('samples must be a finite number');
}
const n = Math.round(v);
if (n < 1) return 1;
return n;
};
lightTrail({ samples: safeSamples(userSamples) }); Type guard
const isSamples = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 64;
Prevention
- Always coerce samples with Math.round and clamp to [1, 64] before passing it in.
- Treat 0/negative as 'unset' and omit the prop rather than passing it.
- Add a unit test that exercises the lower boundary at 1.
When it happens
Trigger: Calling `lightTrail({samples: 0})`, `lightTrail({samples: -4})`, or passing a value that defaults/clamps to a non-positive number. Because the `??` coalescing only fills `undefined`, passing `0` explicitly bypasses the default and hits this guard. Non-integers (e.g. 0.5) are caught one branch earlier by a separate error.
Common situations: Animating `samples` from 0 upward and clamping to 0 at the tail of a spring; reading samples from a config that uses 0 as a sentinel for 'auto'; copying a value from another effect that allows 0 (e.g. blur radius) and reusing it here.
Related errors
- "samples" must be <= ${MAX_SAMPLES}, but got ${samples}
- "${name}" must be a [number, number] tuple
- "${name}" must be a [number, number] tuple
- The "width" and "height" props must be numbers on <Img> when
- The ${formatPropList(conflictingProps)} prop${conflictingPro
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/4b7bf0aa80598afc.
Report an issue: GitHub.