nolimits4web/swiper · warning
Swiper Loop Warning: Loop mode is not compatible with grid.f
Error message
Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`
What it means
Emitted by loopFix in the else-if at src/core/loop/loopFix.ts:95-96 when grid is enabled (grid.rows > 1), grid.fill === 'row', and the slide-count guard for error [3] did NOT fire (it is an else-if). Loop mode clones and repositions slides by index, but grid.fill:'row' lays slides out row-major across columns; the two layouts conflict and Swiper explicitly does not support this combination. Because it is gated behind the else-if, this warning appears only when there ARE enough slides, so a valid-looking config can still warn here.
Source
Thrown at src/core/loop/loopFix.ts:96
? Math.max(slidesPerGroup, Math.ceil(slidesPerView / 2))
: slidesPerGroup;
if (loopedSlides % slidesPerGroup !== 0) {
loopedSlides += slidesPerGroup - (loopedSlides % slidesPerGroup);
}
loopedSlides += params.loopAdditionalSlides!;
swiper.loopedSlides = loopedSlides;
const gridEnabled = swiper.grid && params.grid && params.grid.rows! > 1;
if (
slides.length < slidesPerView + loopedSlides ||
(swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2)
) {
showWarning(
'Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled or not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters',
);
} else if (gridEnabled && params.grid!.fill === 'row') {
showWarning('Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`');
}
const prependSlidesIndexes: number[] = [];
const appendSlidesIndexes: number[] = [];
const cols = gridEnabled ? Math.ceil(slides.length / params.grid!.rows!) : slides.length;
const isInitialOverflow =
initial && cols - (initialSlide as number) < slidesPerView && !bothDirections;
let activeIndex = isInitialOverflow ? (initialSlide as number) : swiper.activeIndex;
if (typeof activeSlideIndex === 'undefined') {
activeSlideIndex = swiper.getSlideIndex(
slides.find((el) => el.classList.contains(params.slideActiveClass!))!,
);
} else {
activeIndex = activeSlideIndex;View on GitHub (pinned to 6138c2a685)
Solutions
- Change grid.fill to 'column' (the default), which is the only fill mode compatible with loop.
- If you must keep grid.fill:'row', disable loop:true.
- Drop the grid module entirely if seamless loop is the priority.
- Validate the combination at config-build time (see defense) so this never reaches loopFix.
Example fix
// before -- loop + grid.fill 'row' -> warning at loopFix.ts:96
new Swiper(el, { loop: true, grid: { rows: 3, fill: 'row' } });
// after -- use the loop-compatible fill, or disable loop
new Swiper(el, { loop: true, grid: { rows: 3, fill: 'column' } }); // supported
// or: new Swiper(el, { grid: { rows: 3, fill: 'row' } }); // no loop Defensive patterns
Strategy: validation
Validate before calling
function assertLoopGridCompatible(p: { loop?: boolean; grid?: { rows?: number; fill?: 'row' | 'column' } }): void {
const rows = p.grid?.rows ?? 1;
if (p.loop && rows > 1 && p.grid?.fill === 'row') {
throw new Error('Swiper loop is incompatible with grid.fill="row"; use grid.fill="column" or disable loop.');
}
}
assertLoopGridCompatible(params); // run before `new Swiper(el, params)` Type guard
function isLoopGridConfigValid(p: { loop?: boolean; grid?: { rows?: number; fill?: 'row' | 'column' } }): boolean {
return !(Boolean(p.loop) && (p.grid?.rows ?? 1) > 1 && p.grid?.fill === 'row');
} Prevention
- Never combine loop:true with grid.fill:'row'; use grid.fill:'column' (the default) when looping.
- Add a config-build assertion so the bad combination fails fast instead of warning at runtime.
- If multi-row row-fill layout is required, disable loop and accept a finite carousel.
- Document the grid.fill choice alongside any loop config so reviewers catch the mismatch.
When it happens
Trigger: { loop:true, grid:{ rows:3, fill:'row' } } with a slide count large enough to pass the slidesPerView + loopedSlides minimum (loopFix.ts:88-91), so execution reaches the else-if at line 95. Any loop + multi-row grid with fill:'row' triggers it regardless of slide count, as long as the count minimum is satisfied.
Common situations: Wanting a multi-row looping carousel and copying a grid.fill:'row' config; reusing a grid layout preset inside a looping slider; version upgrades where grid fill semantics or the loop compatibility check changed; configs assembled from unrelated examples.
Related errors
- Swiper Loop Warning: The number of slides is not even to sli
- Swiper Loop Warning: The number of slides is not even to gri
- Swiper Loop Warning: The number of slides is not enough for
AI-assisted analysis of nolimits4web/swiper@6138c2a685 (2026-08-12).
Data as JSON: /api/errors/57cb1e1a718cefc6.
Report an issue: GitHub.