yikart/AiToEarn · error · AppException
ChannelPaginationDirectionNotSupported
ChannelPaginationDirectionNotSupported
Error message
ChannelPaginationDirectionNotSupported
What it means
normalizeChannelPagination validates cursor-based pagination inputs against a platform's pagination metadata. When the caller asks for ChannelPaginationDirection.Previous but the platform's cursor metadata declares supportsPrevious=false, the helper throws ChannelPaginationDirectionNotSupported because that platform can only paginate forward. The thrown AppException carries the platform and requested direction in its details.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/platform-pagination.helper.ts:35
expectedMode: metadata.mode,
actualMode: normalizedMode,
})
}
switch (normalizedMode) {
case ChannelPaginationMode.Cursor: {
const cursorMetadata = metadata as Extract<ChannelPaginationMetadata, { mode: ChannelPaginationMode.Cursor }>
const limit = normalized.limit ?? cursorMetadata.defaultLimit
if (limit > cursorMetadata.maxLimit) {
throw new AppException(ResponseCode.ChannelPaginationLimitExceeded, {
platform,
limit,
maxLimit: cursorMetadata.maxLimit,
})
}
const direction = normalized.direction ?? ChannelPaginationDirection.Next
if (direction === ChannelPaginationDirection.Previous && !cursorMetadata.supportsPrevious) {
throw new AppException(ResponseCode.ChannelPaginationDirectionNotSupported, {
platform,
direction,
})
}
return { ...normalized, limit, direction }
}
case ChannelPaginationMode.Page: {
const pageMetadata = metadata as Extract<ChannelPaginationMetadata, { mode: ChannelPaginationMode.Page }>
const pageSize = normalized.pageSize ?? pageMetadata.defaultPageSize
if (pageSize > pageMetadata.maxPageSize) {
throw new AppException(ResponseCode.ChannelPaginationPageSizeExceeded, {
platform,
pageSize,
maxPageSize: pageMetadata.maxPageSize,
})
}
return { page: normalized.page ?? 1, pageSize }
}View on GitHub (pinned to d3aa8bea5b)
Solutions
- Check the platform's pagination metadata (cursorMetadata.supportsPrevious) before offering backward pagination, and hide/disable the 'previous' control when it is false.
- Omit the direction field so it defaults to ChannelPaginationDirection.Next and paginate forward from the start.
- Implement client-side backward navigation by keeping a stack of cursors and using the previous cursor with direction Next, instead of requesting direction Previous.
- If the platform genuinely supports backward cursors, fix the integration registration so cursorMetadata.supportsPrevious is true.
Example fix
// before
await listComments(accountId, { cursor, direction: ChannelPaginationDirection.Previous })
// after
const meta = getPlatformPaginationMetadata(platform)
const direction = meta.mode === ChannelPaginationMode.Cursor && meta.supportsPrevious
? ChannelPaginationDirection.Previous
: ChannelPaginationDirection.Next
await listComments(accountId, { cursor, direction }) Defensive patterns
Strategy: validation
Validate before calling
const meta = platformPaginationMetadata[platform]
const canGoPrevious = meta?.mode === ChannelPaginationMode.Cursor && meta.supportsPrevious
if (requested.direction === ChannelPaginationDirection.Previous && !canGoPrevious) {
// use Next or disable backward paging
} Type guard
function supportsPreviousPagination(meta: ChannelPaginationMetadata): meta is Extract<ChannelPaginationMetadata, { mode: ChannelPaginationMode.Cursor; supportsPrevious: true }> {
return meta.mode === ChannelPaginationMode.Cursor && meta.supportsPrevious
} Try / catch
try {
return await listItems({ cursor, direction })
} catch (e) {
if (e instanceof AppException && e.code === ResponseCode.ChannelPaginationDirectionNotSupported) {
return await listItems({ cursor: previousCursorStack.pop(), direction: ChannelPaginationDirection.Next })
}
throw e
} Prevention
- Read the platform's pagination metadata before building list UI controls.
- Only render a 'previous page' button when supportsPrevious is true.
- Keep a client-side cursor stack for backward navigation on forward-only platforms.
- Never reuse direction values across platforms without checking capability.
When it happens
Trigger: Calling any paginated channel listing API (works, comments, etc.) with direction: ChannelPaginationDirection.Previous (or 'previous' in the request body) for a platform whose ChannelPaginationMetadata has { mode: Cursor, supportsPrevious: false }. normalizeChannelPagination is invoked by input/normalizedPagination when a cursor or direction is present in the request.
Common situations: A frontend 'back to previous page' button applied to every platform; code shared across platforms where one platform (e.g. one that only offers forward cursors) rejects the backward navigation the other platforms support; reusing a saved 'Previous' direction from a different platform's list.
Related errors
- ChannelPaginationPageSizeExceeded
- No subtitle entries in response
- No response from Gemini
- Invalid subtitle data: ${z.prettifyError(result.error)}
- Canvas not provided and no vid:// video source found in Trac
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/9b4ecaa726f6f7f0.
Report an issue: GitHub.