lovell/sharp · error · Error
Expected at least two images to join
Error message
Expected at least two images to join
What it means
Thrown when the input to sharp is an array but contains fewer than two elements. The join feature stacks two or more images; a single-element or empty array has nothing to join. Sharp distinguishes this from 'Unsupported input' because the array branch is specifically for joins, and a one-image join is meaningless.
Source
Thrown at lib/input.mjs:102
inputOptions = input;
if (_inputOptionsFromObject(inputOptions)) {
// Stream with options
inputDescriptor.buffer = [];
}
} else if (!is.defined(input) && !is.defined(inputOptions) && is.object(containerOptions) && containerOptions.allowStream) {
// Stream without options
inputDescriptor.buffer = [];
} else if (Array.isArray(input)) {
if (input.length > 1) {
// Join images together
if (!this.options.joining) {
this.options.joining = true;
this.options.join = input.map(i => this._createInputDescriptor(i));
} else {
throw new Error('Recursive join is unsupported');
}
} else {
throw new Error('Expected at least two images to join');
}
} else {
throw new Error(`Unsupported input '${input}' of type ${typeof input}${
is.defined(inputOptions) ? ` when also providing options of type ${typeof inputOptions}` : ''
}`);
}
if (is.object(inputOptions)) {
// failOn
if (is.defined(inputOptions.failOn)) {
if (is.string(inputOptions.failOn) && is.inArray(inputOptions.failOn, ['none', 'truncated', 'error', 'warning'])) {
inputDescriptor.failOn = inputOptions.failOn;
} else {
throw is.invalidParameterError('failOn', 'one of: none, truncated, error, warning', inputOptions.failOn);
}
}
// autoOrient
if (is.defined(inputOptions.autoOrient)) {
if (is.bool(inputOptions.autoOrient)) {View on GitHub (pinned to 56676c6918)
Solutions
- Ensure the array has at least two valid image inputs before calling sharp.
- Guard the length: if (images.length >= 2) sharp(images) else handleSingle(images[0]).
- Filter defensively and assert the count before the join call.
Example fix
// before
sharp(images.filter(Boolean), { join: {} })
// after
const valid = images.filter(Boolean);
if (valid.length < 2) throw new Error('need >= 2 images to join');
sharp(valid, { join: {} }) Defensive patterns
Strategy: validation
Validate before calling
function joinInput(images) {
const valid = images.filter(Boolean);
if (valid.length < 2) throw new Error(`Join needs >= 2 images, got ${valid.length}`);
return valid;
}
sharp(joinInput(images), { join: {} }); Type guard
function isJoinableArray(input) {
return Array.isArray(input) && input.length >= 2;
} Prevention
- Filter and assert length >= 2 before calling sharp with an array.
- Handle the single-image case separately rather than relying on sharp to error.
- Watch for empty arrays from queries/filters.
When it happens
Trigger: Calling sharp([]) with an empty array, or sharp([singleImage]) with exactly one element. Dynamically building a join list that filters down to one or zero items at runtime: sharp(images.filter(Boolean)) where most are null.
Common situations: Filtering or slicing an image list before joining without checking the resulting length. Off-by-one errors when chunking. Empty result sets from a database query fed directly into sharp.
Related errors
- Recursive join is unsupported
- Expected input to be an array of images to join
- Invalid input
- Unsupported input '${input}' of type ${typeof input}${is.def
- Expected width, height and channels for raw pixel input
AI-assisted analysis of lovell/sharp@56676c6918 (2026-08-13).
Data as JSON: /api/errors/78464520e9480731.
Report an issue: GitHub.