marktext/marktext · error · Error
No pages registered for tab "${tab}"
Error message
No pages registered for tab "${tab}" What it means
Thrown by firstPageOfTab() in the website docs-nav module when ALL_PAGES contains no page whose `tab` equals the requested DocTabId. ALL_PAGES is built at module load from DOC_TABS ('user' | 'dev'); the function is used by the /docs redirect and tab-switch fallback to find the first page of a tab.
Source
Thrown at packages/website/src/lib/docs-nav.ts:161
/** prev / next page in the flat ordered list. */
export function neighborsFor(slug: string[]): {
prev: DocPageWithCtx | null
next: DocPageWithCtx | null
} {
const entry = PAGE_BY_KEY.get(slug.join('/'))
if (!entry) return { prev: null, next: null }
const { index } = entry
return {
prev: index > 0 ? ALL_PAGES[index - 1] : null,
next: index < ALL_PAGES.length - 1 ? ALL_PAGES[index + 1] : null
}
}
/** First page of a given tab — used for `/docs` redirect and tab switch fallback. */
export function firstPageOfTab(tab: DocTabId): DocPageWithCtx {
const p = ALL_PAGES.find((page) => page.tab === tab)
if (!p) throw new Error(`No pages registered for tab "${tab}"`)
return p
}
View on GitHub (pinned to e52106fd1c)
Solutions
- Ensure every DocTab in DOC_TABS has at least one group with at least one page.
- Guard the call: const p = ALL_PAGES.find(...); return p ?? ALL_PAGES[0] to avoid crashing the redirect.
- Run the docs build (`pnpm --filter marktext-website build`) which exercises the nav and surfaces the regression.
- Keep the DocTabId type in sync with DOC_TABS ids so no unregistered tab id is callable.
Example fix
// before
export function firstPageOfTab(tab: DocTabId): DocPageWithCtx {
const p = ALL_PAGES.find((page) => page.tab === tab)
if (!p) throw new Error(`No pages registered for tab "${tab}"`)
return p
}
// after
export function firstPageOfTab(tab: DocTabId): DocPageWithCtx {
const p = ALL_PAGES.find((page) => page.tab === tab)
if (!p) throw new Error(`No pages registered for tab "${tab}". Add at least one page to DOC_TABS for this tab.`)
return p
} Defensive patterns
Strategy: validation
Validate before calling
function tabHasPages(tab: DocTabId): boolean {
return ALL_PAGES.some((p) => p.tab === tab)
} Type guard
function tabHasPages(tab: DocTabId): boolean {
return ALL_PAGES.some((p) => p.tab === tab)
} Prevention
- Keep every DOC_TABS entry populated with at least one page.
- Add a unit test asserting each DocTabId has >=1 page in ALL_PAGES.
- Sync the DocTabId union with DOC_TABS ids.
- Guard firstPageOfTab callers against the throw.
When it happens
Trigger: firstPageOfTab called with a DocTabId ('user' or 'dev') whose DOC_TABS entry has an empty groups[].pages array; a tab id passed that is not present in DOC_TABS at all (type cast around the union).
Common situations: A docs content edit removed all pages from a tab but left the tab id referenced by a redirect. A new DocTabId value added to the type union before pages are registered. A refactor of DOC_TABS that leaves a tab with zero groups.
Related errors
- Translation file not found for language: ${language}
- Unsupported uploader: ${currentUploader}
- Can not load static preference.json file
- failed to load docs index
AI-assisted analysis of marktext/marktext@e52106fd1c (2026-08-12).
Data as JSON: /api/errors/0d9f9f1bcd3d1c9c.
Report an issue: GitHub.