Every error message the SDK and API give a website, and every common symptom with pages, previews, cache refresh, types, SEO and regions, with the cause and the fix.
Reference13 min read
Find the message or symptom, then the cause and fix. Configuration › API playground is the quickest way to see what the API answers for a given address, region and key.
Error messages
From the client
A baseUrl is required
Cause
CMS_API_URL is not set where the code runs, including during next build
Fix
Set it in .env.local and in your hosting, for builds and for running
An apiKey is required
Cause
CMS_PUBLIC_KEY is not set, or lib/cms.ts was imported into browser code, where server settings are empty
Fix
Set it. Add import 'server-only' to lib/cms.ts so browser imports fail at build time with a clear message.
A secret CMS key must never be used in browser code. Use a public cms_pk_ key here.
Cause
A cms_sk_ key reached a client created in the browser
Fix
Create clients with secret keys only in server code. In the browser, use a public key.
Previewing needs a previewKey on the client
Cause
A call with preview: true, but the client has no previewKey
Fix
Set CMS_PREVIEW_KEY on the website that shows previews. On the live website, do not pass preview: true; draft mode is never on there unless someone opened a preview link.
Pass the CMS client, or set CMS_API_URL
Cause
CmsBridge or createPreviewHandler was used without client, and CMS_API_URL is not set
Fix
Pass client={cms} or { client: cms }
The webhook secret is required
Cause
createRevalidateHandler was created without a secret, often at build time
Fix
Set CMS_WEBHOOK_SECRET, or create the handler inside the route as in step 15 of Connect a website
Message
Cause
Fix
A baseUrl is required
CMS_API_URL is not set where the code runs, including during next build
Set it in .env.local and in your hosting, for builds and for running
An apiKey is required
CMS_PUBLIC_KEY is not set, or lib/cms.ts was imported into browser code, where server settings are empty
Set it. Add import 'server-only' to lib/cms.ts so browser imports fail at build time with a clear message.
A secret CMS key must never be used in browser code. Use a public cms_pk_ key here.
A cms_sk_ key reached a client created in the browser
Create clients with secret keys only in server code. In the browser, use a public key.
Previewing needs a previewKey on the client
A call with preview: true, but the client has no previewKey
Set CMS_PREVIEW_KEY on the website that shows previews. On the live website, do not pass preview: true; draft mode is never on there unless someone opened a preview link.
Pass the CMS client, or set CMS_API_URL
CmsBridge or createPreviewHandler was used without client, and CMS_API_URL is not set
Pass client={cms} or { client: cms }
The webhook secret is required
createRevalidateHandler was created without a secret, often at build time
Set CMS_WEBHOOK_SECRET, or create the handler inside the route as in step 15 of Connect a website
From the API
The client turns error answers into these errors, all with status, code and message:
CmsAuthError
Status
401
Common causes
The key is mistyped, revoked or expired. A public key asked for drafts. A secret key was sent from a browser. The key may not read the region or language asked for.
Fix
Check the key in Configuration › API keys: its environment, regions, languages and expiry. Create a new one if in doubt.
CmsNotFoundError
Status
404
Common causes
getPage: nothing published at that address in that region. getGlobal or getNavigation: no entry or menu with that key. Any call: the region or language does not exist.
Fix
Use find… or resolve where missing is normal. Check the key, region and language in the playground.
CmsRateLimitError
Status
429
Common causes
More than 15,000 requests a minute from one key or IP address. retryAfter says how many seconds to wait.
The CMS could not be reached, The CMS did not answer within 5000ms, or The CMS returned 503, after the retries
Fix
Usually brief. Cached pages keep being served. See "When the CMS cannot be reached" in Deploy your website.
CmsError
Status
400
Common causes
code: "bad_request": an unknown sort value, a filter key with characters other than letters, digits and underscores, or an include other than fields or references
Fix
Fix the call. The message says which part is wrong.
Error
Status
Common causes
Fix
CmsAuthError
401
The key is mistyped, revoked or expired. A public key asked for drafts. A secret key was sent from a browser. The key may not read the region or language asked for.
Check the key in Configuration › API keys: its environment, regions, languages and expiry. Create a new one if in doubt.
CmsNotFoundError
404
getPage: nothing published at that address in that region. getGlobal or getNavigation: no entry or menu with that key. Any call: the region or language does not exist.
Use find… or resolve where missing is normal. Check the key, region and language in the playground.
CmsRateLimitError
429
More than 15,000 requests a minute from one key or IP address. retryAfter says how many seconds to wait.
The CMS could not be reached, The CMS did not answer within 5000ms, or The CMS returned 503, after the retries
Usually brief. Cached pages keep being served. See "When the CMS cannot be reached" in Deploy your website.
CmsError
400
code: "bad_request": an unknown sort value, a filter key with characters other than letters, digits and underscores, or an include other than fields or references
Fix the call. The message says which part is wrong.
All of them extend CmsError, so error instanceof CmsError catches every API error:
The token is more than an hour old, was made for another space, or was cut short when copied
Fix
Reopen the page in the editor, which makes a new token
Answer
Cause
Fix
400 A preview token is required
The address has neither ?token= nor ?preview=
Open previews from the editor
401 That preview link is invalid or has expired
The token is more than an hour old, was made for another space, or was cut short when copied
Reopen the page in the editor, which makes a new token
From the webhook route
401 Bad signature
Cause
CMS_WEBHOOK_SECRET is wrong or incomplete, or something changed the body on the way
Fix
Copy the whole secret, including whsec_. Make sure no proxy rewrites the body.
401 The message is too old
Cause
Your server's clock is more than five minutes out
Fix
Sync the clock with NTP
503 with not_configured
Cause
Your route answers this while CMS_WEBHOOK_SECRET is not set
Fix
Set it and redeploy
404 or 405
Cause
The webhook's address is wrong, or the route has no POST
Fix
Check the path and that the file is app/api/revalidate/route.ts exporting POST
307, 308
Cause
The address redirects, for example to www or to add a slash
Fix
Register the final address
Answer
Cause
Fix
401 Bad signature
CMS_WEBHOOK_SECRET is wrong or incomplete, or something changed the body on the way
Copy the whole secret, including whsec_. Make sure no proxy rewrites the body.
401 The message is too old
Your server's clock is more than five minutes out
Sync the clock with NTP
503 with not_configured
Your route answers this while CMS_WEBHOOK_SECRET is not set
Set it and redeploy
404 or 405
The webhook's address is wrong, or the route has no POST
Check the path and that the file is app/api/revalidate/route.ts exporting POST
307, 308
The address redirects, for example to www or to add a slash
Register the final address
From the type generator
Set CMS_API_URL and CMS_PUBLIC_KEY, or pass --url and --key.
Cause
The settings were not loaded. npm scripts do not read .env.local by themselves.
Fix
Use node --env-file-if-exists=.env.local as in step 7 of the tutorial, or pass --url and --key
The CMS answered 401 for …/schema
Cause
The key is wrong, revoked or expired
Fix
Check it in Configuration › API keys
The CMS answered 404 for …/schema
Cause
The address is wrong
Fix
Use https://api.bifrostorbit.com/cms
Usage: cms-orbit generate …
Cause
The command was run without generate
Fix
npx cms-orbit generate --out cms/types.ts
Message
Cause
Fix
Set CMS_API_URL and CMS_PUBLIC_KEY, or pass --url and --key.
The settings were not loaded. npm scripts do not read .env.local by themselves.
Use node --env-file-if-exists=.env.local as in step 7 of the tutorial, or pass --url and --key
The CMS answered 401 for …/schema
The key is wrong, revoked or expired
Check it in Configuration › API keys
The CMS answered 404 for …/schema
The address is wrong
Use https://api.bifrostorbit.com/cms
Usage: cms-orbit generate …
The command was run without generate
npx cms-orbit generate --out cms/types.ts
In development
A dashed box: No renderer registered for "…"
Cause
The page has a component that is not in the registry. Production renders nothing in its place.
Fix
Add it to the registry. If it is new, regenerate the types first.
You're importing a component that needs "server-only"
Cause
A client component imports lib/cms.ts, directly or through another file
Fix
Fetch in a server component and pass the data down as props
Functions cannot be passed directly to Client Components
Cause
The registry was passed as a prop from a server component to a client component
Fix
Import the registry inside the client file, as components/live-page.tsx does
async/await is not yet supported in Client Components
Cause
An async block component is drawn by CmsLivePage, which runs in the browser
Fix
Fetch its data in the page route and pass it down; see "Components that need more data" in Render components
Invalid src prop … hostname "…" is not configured
Cause
next/image with an image host not in remotePatterns
Fix
Add the host from the image's url to images.remotePatterns
Message
Cause
Fix
A dashed box: No renderer registered for "…"
The page has a component that is not in the registry. Production renders nothing in its place.
Add it to the registry. If it is new, regenerate the types first.
You're importing a component that needs "server-only"
A client component imports lib/cms.ts, directly or through another file
Fetch in a server component and pass the data down as props
Functions cannot be passed directly to Client Components
The registry was passed as a prop from a server component to a client component
Import the registry inside the client file, as components/live-page.tsx does
async/await is not yet supported in Client Components
An async block component is drawn by CmsLivePage, which runs in the browser
Fetch its data in the page route and pass it down; see "Components that need more data" in Render components
Invalid src prop … hostname "…" is not configured
next/image with an image host not in remotePatterns
Add the host from the image's url to images.remotePatterns
TypeScript
Property 'hero' is missing in type … on defineRegistry
Cause
A component in the generated types has no entry
Fix
Add it, or point it at () => null if it never appears on pages
Property 'heading' does not exist on type …, or every field is unknown
Cause
The generated types are not loaded
Fix
Keep import '@/cms/types' in cms/registry.tsx, and check tsconfig.json includes the file
A field that exists in the CMS is missing from the type
Cause
The types are out of date
Fix
npm run cms:types
Type 'string' is not assignable to type 'CmsEntry<…>'
Cause
Types were generated with --include references, but the page was read without include: ['references'], or the other way round
Fix
Use both or neither
Error
Cause
Fix
Property 'hero' is missing in type … on defineRegistry
A component in the generated types has no entry
Add it, or point it at () => null if it never appears on pages
Property 'heading' does not exist on type …, or every field is unknown
The generated types are not loaded
Keep import '@/cms/types' in cms/registry.tsx, and check tsconfig.json includes the file
A field that exists in the CMS is missing from the type
The types are out of date
npm run cms:types
Type 'string' is not assignable to type 'CmsEntry<…>'
Types were generated with --include references, but the page was read without include: ['references'], or the other way round
Use both or neither
Symptoms
Pages
Every page is the 404 page
Likely cause
The region does not match, or nothing is published in the environment the key belongs to
Fix
Check CMS_DEFAULT_REGION and the key's environment. Try the address in the playground with the same key.
One page is 404, but it exists in the CMS
Likely cause
It is published in another region or environment, or only saved as a draft. Or the path has a trailing slash or a region prefix.
Fix
Publish it in the right place. Pass the address as the CMS stores it: /services, not /services/ or /de/services.
A page shows the wrong language
Likely cause
No locale was passed, so the region's default answered, or a fallback answered
Fix
Pass locale. Check page.meta.fallbackApplied. Use strict: true to refuse fallbacks.
A component is missing, with no message
Likely cause
It is not in the registry, in production
Fix
Add it
A link does not appear
Likely cause
It points at a page that is not published, so href is null
Fix
Publish the page, or render the label without a link
Menu items are missing
Likely cause
They link to pages not published in this region and language, or are hidden
Fix
Publish the pages, or check the menu in Menus
A list is empty
Likely cause
The content type key is wrong, the entries are in another language (lists do not fall back), or they are global entries, which lists leave out
Fix
Check type, locale and the content type
References arrive as ids
Likely cause
The call has no include: ['references']
Fix
Add it
An image has no srcset
Likely cause
sizes was not passed to CmsImage, or the image address has no /uploads/
Fix
Pass sizes
Rich text shows as HTML tags
Likely cause
It was rendered as text
Fix
Use RichText
What you see
Likely cause
Fix
Every page is the 404 page
The region does not match, or nothing is published in the environment the key belongs to
Check CMS_DEFAULT_REGION and the key's environment. Try the address in the playground with the same key.
One page is 404, but it exists in the CMS
It is published in another region or environment, or only saved as a draft. Or the path has a trailing slash or a region prefix.
Publish it in the right place. Pass the address as the CMS stores it: /services, not /services/ or /de/services.
A page shows the wrong language
No locale was passed, so the region's default answered, or a fallback answered
Pass locale. Check page.meta.fallbackApplied. Use strict: true to refuse fallbacks.
A component is missing, with no message
It is not in the registry, in production
Add it
A link does not appear
It points at a page that is not published, so href is null
Publish the page, or render the label without a link
Menu items are missing
They link to pages not published in this region and language, or are hidden
Publish the pages, or check the menu in Menus
A list is empty
The content type key is wrong, the entries are in another language (lists do not fall back), or they are global entries, which lists leave out
Check type, locale and the content type
References arrive as ids
The call has no include: ['references']
Add it
An image has no srcset
sizes was not passed to CmsImage, or the image address has no /uploads/
Pass sizes
Rich text shows as HTML tags
It was rendered as text
Use RichText
Previews
The preview area is blank or refuses to connect
Likely cause
Your website sends X-Frame-Options or a frame-ancestors that does not allow https://app.bifrostorbit.com, or the Preview URL is wrong or not https
Fix
See "Let the editor show your website" in Deploy your website. Check Preview URL in the space's Settings.
The preview shows the published page, not the draft
Likely cause
proxy.ts is missing, so ?preview= is ignored. Or the page route does not pass preview from draftMode(). Or the website has no preview key.
Fix
Add the proxy and preview route from step 14 of the tutorial
The preview shows the draft in a new tab, but not inside the editor
Likely cause
The draft mode cookie is blocked inside the frame: the website runs with next dev, is not https, or the browser blocks cookies in frames from other websites, as Safari does by default
Fix
Test with next build and next start or a deployed website, use https, or use Open in a new tab
The preview only changes after saving
Likely cause
The page is drawn with CmsPage, not CmsLivePage
Fix
Use PageBody and LivePage from step 14
The header or title does not change as editors type
Likely cause
Only the page body is live. Everything else changes when the preview reloads after saving.
Fix
Expected
Clicking a block does not select it
Likely cause
The component has no data-cms-id={block.id} on its outer element, or the bridge is not loaded
Fix
Add the attribute. Check <CmsBridge client={cms} /> is in the layout.
Clicking selects the parent block
Likely cause
The nested block you draw yourself has no data-cms-id
Fix
Add data-cms-id={node.id}
A page in another region previews the default region
Likely cause
The Preview URL has no region prefix
Fix
Add each region under Other preview URLs and choose it above the preview; see Regions and languages
Visitors see drafts
Likely cause
Impossible unless they have the draft mode cookie, which only the preview route sets after the CMS accepts a token
Fix
Check that the live website has no preview key, and that your own code does not pass preview: true
What you see
Likely cause
Fix
The preview area is blank or refuses to connect
Your website sends X-Frame-Options or a frame-ancestors that does not allow https://app.bifrostorbit.com, or the Preview URL is wrong or not https
See "Let the editor show your website" in Deploy your website. Check Preview URL in the space's Settings.
The preview shows the published page, not the draft
proxy.ts is missing, so ?preview= is ignored. Or the page route does not pass preview from draftMode(). Or the website has no preview key.
Add the proxy and preview route from step 14 of the tutorial
The preview shows the draft in a new tab, but not inside the editor
The draft mode cookie is blocked inside the frame: the website runs with next dev, is not https, or the browser blocks cookies in frames from other websites, as Safari does by default
Test with next build and next start or a deployed website, use https, or use Open in a new tab
The preview only changes after saving
The page is drawn with CmsPage, not CmsLivePage
Use PageBody and LivePage from step 14
The header or title does not change as editors type
Only the page body is live. Everything else changes when the preview reloads after saving.
Expected
Clicking a block does not select it
The component has no data-cms-id={block.id} on its outer element, or the bridge is not loaded
Add the attribute. Check <CmsBridge client={cms} /> is in the layout.
Clicking selects the parent block
The nested block you draw yourself has no data-cms-id
Add data-cms-id={node.id}
A page in another region previews the default region
The Preview URL has no region prefix
Add each region under Other preview URLs and choose it above the preview; see Regions and languages
Visitors see drafts
Impossible unless they have the draft mode cookie, which only the preview route sets after the CMS accepts a token
Check that the live website has no preview key, and that your own code does not pass preview: true
Publishing and cache
Changes take up to a minute or more to appear
Likely cause
No webhook, or it fails
Fix
Create one and check Deliveries
The webhook answers 200 but the page does not change
Likely cause
The client has no cache: { tags: true }. Or the region you read with is a short code, or not set, so the tag does not match. Or a CDN holds the old HTML.
The webhook answers 200 but the page does not change
The client has no cache: { tags: true }. Or the region you read with is a short code, or not set, so the tag does not match. Or a CDN holds the old HTML.
Your layout sets title.template, and the CMS title already has the template from SEO › Settings
Fix
Remove the layout's template
Canonical links or the sitemap use the wrong domain
Likely cause
Configuration › Domains has no primary domain for the environment, or the wrong one
Fix
Add and verify the domain, and make it primary
The sitemap is empty
Likely cause
No domain is set up, every page is no-index or left out of the sitemap, or the key is from another environment
Fix
Check the domains and the pages' SEO settings
robots.txt says Disallow: / on the live website
Likely cause
The website uses a key from a non-indexable environment, such as Staging
Fix
Use a key from Production
No hreflang links
Likely cause
The page exists in one language only, or toMetadata is not used
Fix
Expected for one language; otherwise use toMetadata
Next.js complains about both robots.ts and robots.txt/route.ts
Likely cause
Both exist
Fix
Keep one
What you see
Likely cause
Fix
The site name appears twice in titles
Your layout sets title.template, and the CMS title already has the template from SEO › Settings
Remove the layout's template
Canonical links or the sitemap use the wrong domain
Configuration › Domains has no primary domain for the environment, or the wrong one
Add and verify the domain, and make it primary
The sitemap is empty
No domain is set up, every page is no-index or left out of the sitemap, or the key is from another environment
Check the domains and the pages' SEO settings
robots.txt says Disallow: / on the live website
The website uses a key from a non-indexable environment, such as Staging
Use a key from Production
No hreflang links
The page exists in one language only, or toMetadata is not used
Expected for one language; otherwise use toMetadata
Next.js complains about both robots.ts and robots.txt/route.ts
Both exist
Keep one
Builds and types
The build fails with A baseUrl is required
Likely cause
The settings are not available at build time
Fix
Add them to the build environment
The build is slow and makes many CMS requests
Likely cause
generateStaticParams returns pages
Fix
Return [] and let pages build on first visit
CI fails at git diff --exit-code cms/types.ts
Likely cause
Someone changed the schema and the committed types are out of date
Fix
Run npm run cms:types and commit
What you see
Likely cause
Fix
The build fails with A baseUrl is required
The settings are not available at build time
Add them to the build environment
The build is slow and makes many CMS requests
generateStaticParams returns pages
Return [] and let pages build on first visit
CI fails at git diff --exit-code cms/types.ts
Someone changed the schema and the committed types are out of date
Run npm run cms:types and commit
Still stuck? Try the same request in Configuration › API playground with the same key, region and language as your website. If the playground answers as expected, the problem is in the website; if not, it is in the content or the key.