Find the message or the symptom you see, then read the cause and the fix. Messages are quoted
exactly as the CLI, the SDK or the dashboard print them (most are Dutch). <…> marks a part that
varies.
CLI and login
| Symptom | Cause | Fix |
|---|---|---|
KWISPLE_URL en KWISPLE_TOKEN ontbreken. Voer kwisple login en kwisple link uit, of zet ze in de omgeving (CI). | push, dev, status, seed or export found no .env or .env.local with both variables, and they are not in the environment. | Run kwisple link in the project folder. In CI, set both as secrets (kwisple ci-token --gh). |
Niet aangemeld op <origin>. Voer eerst kwisple login uit. | link or ci-token has no CLI token for that dashboard. | kwisple login. If you log in on an agency's own dashboard host, pass the same --dashboard <url> to every command, or rely on KWISPLE_DASHBOARD_ORIGIN in the project's .env. |
Dashboard niet bereikbaar op <origin>. Een ander adres? Gebruik --dashboard <url>. | The CLI talks to the wrong dashboard or it is down. The order is: --dashboard, KWISPLE_DASHBOARD_URL, KWISPLE_DASHBOARD_ORIGIN in the project's .env, your last login, https://app.kwisple.com. | Pass --dashboard. Locally: --dashboard http://localhost:4100. |
De code is verlopen. Voer kwisple login opnieuw uit. | The device code was not approved within its lifetime. | Run kwisple login again and approve in the browser. |
Toegang geweigerd in de browser. | Someone clicked deny on the /cli page. | kwisple login again. |
Je sleutel is ingetrokken. Voer kwisple login opnieuw uit. | The CLI token was revoked under Instellingen → Koppelingen, or by kwisple logout on another shell. | kwisple login. |
Je hebt geen klanten waar je een website mag koppelen. … | Your account has no client where you may link a site. Linking and pushing are agency work. | Ask the agency to add you to its team, or to link the site. |
Je mag deze website niet koppelen. Vraag het aan iemand van het bureau. | You can see the client but lack the developer right on it. | Ask someone of the agency. |
Deze website is niet op maat gebouwd. Enkel websites met eigen code kan je koppelen. | The site is a hosted block site or an external site. | Link a custom-code site, or create one with + Nieuwe website in kwisple link. |
Website niet gevonden of geen toegang. | --site <id|slug> does not match a site you can reach. | Run kwisple link without --site to pick from the list. |
Kies een website met --site <id|slug>, of maak er een met --client <klant> --name <naam>: | kwisple link runs without a terminal (CI, a script) and needs to know the site. | Use one of the --site values it lists below the message. |
Welke website? Voer kwisple link uit in dit project, of geef --site <id|slug> op. | kwisple ci-token found no KWISPLE_SITE. | Run it in a linked project or pass --site. |
gh secret set lukte niet; zet ze zelf: | The GitHub CLI is missing, not logged in, or not in a repository. | Copy the two printed values into the repository's Actions secrets. |
.env.local zet ook <keys>; die waarden winnen. | .env.local has older KWISPLE_* values that override the new .env. | Remove those keys from .env.local. |
Te veel aanmeldpogingen. Probeer zo opnieuw. | The device login is rate limited. | Wait a minute. |
cms.config.ts niet gevonden in <dir>. | You are not in the project root, or the file has another name. | cd to the root, or pass --config <pad>. |
Push and model
| Symptom | Cause | Fix |
|---|---|---|
cms.config.ts moet een schema exporteren (export default defineSchema({...})). | The file has no default export (or named schema) with a sections array. | export default defineSchema({ sections: [...] }). |
Contentmodel klopt niet: followed by lines | Local validation failed: reserved handles, unknown tab fields, duplicates, a renamedFrom that still exists. | Fix each line. See Schema as code. |
Niet toegepast: deze push bevat destructieve wijzigingen., exit code 2 | A field, section or global set was removed or retyped, or a field's translation changed. | Check the list. If intended: kwisple push --force. A rename? Use renamedFrom. See Workflow. |
Dit token heeft geen "schema"-rechten. (403 forbidden) | The token lacks Contentmodel pushen. Production tokens and hosting tokens should not have it. | Use the token from kwisple link locally or a CI token in CI. |
Ongeldig of ingetrokken API-token. (401 unauthorized) | The token was revoked, or re-linking replaced it. | kwisple link again (locally) or a new kwisple ci-token (CI). |
Deze site is een gehoste site met het standaardschema; … (409) | You pushed to a hosted site. | Only custom-code sites take a pushed model. |
| Editors do not see your new field | You only ran kwisple dev: the change is in the development model. | kwisple push, or merge so CI pushes. |
kwisple push says Geen wijzigingen, but production renders without the new field | The deployment was built from older code, or reads with KWISPLE_SCHEMA=dev. | Redeploy; never set KWISPLE_SCHEMA in production. |
[kwisple] Het contentmodel in je code (…) is niet wat het platform … gebruikt (…). | The model check: your build's cms.config.ts differs from the pushed model, e.g. a deploy without a push. | Push before (or as part of) the build. See Workflow. |
| CI job fails on a pull request | kwisple push --dry-run fails only on an invalid model or a bad token. | Read the job log; destructive changes do not fail the dry run. |
Deze site heeft al inhoud. Gebruik --force om de kit er toch bij te zetten. | kwisple seed into a site that already has published content. | Seed an empty site, or --force to add the kit next to it. |
kwisple seed lists problems such as sectie bestaat niet in het contentmodel and places nothing | Not a single kit entry could be published (wrong section handles, model not pushed). | Push the model first; check section handles in cms/seed.json. |
Rendering
| Symptom | Cause | Fix |
|---|---|---|
KWISPLE_URL ontbreekt. Voer npx kwisple login en npx kwisple link uit (schrijft .env). (Next starter) | The variable is missing at runtime or build time. | Set KWISPLE_URL and KWISPLE_TOKEN at your host for the build and the server. |
KWISPLE_URL ontbreekt. Voer npx kwisple link uit (schrijft .env) of zet het in de omgeving van je host. (Astro) | Same, in Astro's runtime; a production Node server does not read .env by itself. | Set the variables in the host environment, or start with node --env-file=.env. |
client.entry() returns null for a page that exists | The entry is not published, is hidden in that locale, has a future Online vanaf, or the URI differs (homepage: __home__, other locales: prefix stripped by entryByPath). | Publish it; use entryByPath(path) in the catch-all route. |
KwispleError with code bad_request from entries() | where, orderBy or select names a field the queried sections do not have, or a kind that cannot be filtered. | Read the message; see Querying entries. |
KwispleError(500, "no_site") / Site niet gevonden. | The platform answered without a site for the token. | Check that KWISPLE_URL points at the platform's web app and the token belongs to this site. |
Images fail in next/image | The asset host is not allowed in remotePatterns. | Set KWISPLE_ASSET_ORIGIN (written by kwisple link) before next build; the starter's next.config.ts reads it. |
A new field is undefined in production only | The model with that field was never pushed. | kwisple push; turn on the model check. |
| Old block types still render | Your cached SDK answers predate the publish. | See Revalidation and caching. |
Preview
| Symptom | Cause | Fix |
|---|---|---|
| Stel eerst een preview-URL in bij Instellingen › Ontwikkeling. | The site has no Preview-URL. | Fill it in (your /api/preview); kwisple link fills it in only when empty. |
| Live preview stays empty locally | The Preview-URL points at another port than your running dev server. | Set it to http://localhost:<port>/api/preview. |
Preview-token ontbreekt. (400) | /api/preview was opened without ?token=. | Open the preview from the dashboard. |
Preview-token ongeldig of verlopen. Open de preview opnieuw vanuit het dashboard. (401) | The preview token expired (after an hour) or the entry is gone. | Reopen the preview from the dashboard. |
Dit token heeft geen "preview"-rechten. (403), or /api/preview fails with a server error | The site's own token lacks the preview scope (Preview (concepten)), so it cannot verify preview tokens or read drafts. | Use a token with read + preview. |
| Preview frame is blank in production | The page forbids framing (X-Frame-Options, or frame-ancestors without the dashboard origin), or the preview cookie is refused. In production the cookie is SameSite=None; Secure and needs https. | Allow the dashboard origin in frame-ancestors, drop X-Frame-Options, serve the site over https. |
| Preview does not refresh after typing | <LivePreview> is missing or its allowedOrigin differs from the dashboard origin. | Render <LivePreview allowedOrigin={process.env.KWISPLE_DASHBOARD_ORIGIN} /> while draft mode is on. |
See Live preview and revalidation.
Revalidation and caching
After a publish the dashboard reports De site kon niet verwittigd worden: <reason>. De inhoud is
wel opgeslagen. when the webhook failed. The content is saved; only your site's cache was not
told.
| Reason | Cause | Fix |
|---|---|---|
Site antwoordde met 401. | /api/revalidate rejected the signature (Ongeldige handtekening.): KWISPLE_WEBHOOK_SECRET differs from Webhook-geheim, e.g. after Vernieuwen. | Copy the current secret into the deployment and redeploy. |
Site antwoordde met 404. | The route is not deployed at that URL. | Check Webhook bij publiceren and that /api/revalidate exists (Astro injects it only when the site renders on demand). |
Site antwoordde met <status>. (5xx) | The route crashed. | Check the site's logs. |
Webhook-URL stuurt door; gebruik de eindbestemming. | The URL redirects (e.g. http → https, bare domain → www). Redirects are never followed. | Enter the final URL. |
Webhook kon niet worden afgeleverd. | Timeout (5 s) or connection error. | Check the site is up and reachable from the internet. |
Enkel https-URL's zijn toegestaan. / Deze URL is niet toegestaan. | In production the webhook must be https and on a public address. | Use the public https address. |
| Symptom | Cause | Fix |
|---|---|---|
Cache legen shows website (webhook mislukt) / Cache gedeeltelijk geleegd. | The platform's caches were emptied, the webhook was not accepted. | Same reasons as above. Geen webhook ingesteld.: fill in Webhook bij publiceren. |
| A static site never shows new content | A static build has no /api/revalidate. | Under Hosting & deploys choose Opnieuw bouwen (rebuild on publish), or point the webhook at a deploy hook. |
| Content updates on one server instance only (Astro) | The Astro cache lives in the memory of each process; the webhook reaches one. | Run one instance, or lower cacheTtl. |
| Content changes, but visitors keep seeing the old HTML | A CDN or proxy in front of the site caches HTML (e.g. the Cloudflare proxy). The webhook cannot purge it. | Turn the proxy off for the site (DNS only) or make it not cache HTML. See Caching. |
| A redirect added by hand works only after a few minutes | matchRedirect answers, misses included, are cached for five minutes. | Wait, or Cache legen. |
| A brand colour change does not show | The site has no Webhook bij publiceren, so the brand save could not tell it, or the site is a static build. | Set the webhook URL; static sites need a rebuild. |
Deploys
| Symptom | Cause | Fix |
|---|---|---|
| The status stays Aangevraagd (requested) | A deploy-hook connection without a status address cannot read the build state. | Fill in Status-adres (optioneel) when connecting under Hosting & deploys, or check the host. |
| Mislukt (failed) | The host's build failed. | Open the host's log; a missing KWISPLE_* variable is the usual cause. With Eigen host (deploy hook) you set them yourself. |
| Cloudflare is not offered as a host | The platform has no Cloudflare credentials configured. | Use Eigen host (deploy hook), or ask the platform operator. |
| Publishing does not start a build | Als inhoud verandert is Alleen verversen, or the platform's worker is not running. Builds start at most once a minute. | Choose Opnieuw bouwen for static sites. |
| The build renders the old model | The host built before CI pushed the model. | Turn off the host's automatic production builds and set KWISPLE_DEPLOY_HOOK so CI starts the build after the push. See CI and automation. |
See Hosting and deploys.
Apps
| Symptom | Cause | Fix |
|---|---|---|
| The app is missing from the menu | The model with apps was only synced by kwisple dev, never pushed: apps are read from the live model. | kwisple push. |
| The app is missing for some people | Their level in the app's area is below its level (or teamOnly is set). During a read-only subscription only level: "view" apps show. | Check the area and level in defineApp against the client's access policy. |
| The app of a second site does not show | Another site of the client declares the same handle; the first site by name wins. | Use distinct handles. |
| Deze app is nog niet bereikbaar | The site has no Webhook-geheim yet, its Site-URL is empty or not http(s), or path resolves to another origin. | Run kwisple link (creates the secret), fill in the Site-URL, keep path relative. |
| Blank frame | X-Frame-Options, or frame-ancestors without the dashboard origin. | See Building the page. |
Het dashboard gaf geen sessie door. | Wrong dashboardOrigin in the browser, or the page is framed by something else. | Pass KWISPLE_DASHBOARD_ORIGIN to connectApp. |
Deze pagina werkt enkel binnen het dashboard. | Someone opened the app's URL directly. | Expected: apps only run inside the dashboard. |
| Deze app is gesloten omdat je sessie afliep of je geen toegang meer hebt. | Session renewal failed: rights changed, the app was removed or the site unlinked. | Reload; check the person's level. |
See Declaring an app.
Domains
| Symptom | Cause | Fix |
|---|---|---|
Nog niet gevonden: <records>. Een DNS-wijziging kan tot een uur duren. | The TXT record on _site-verify.<domein> or the A/AAAA/CNAME records are not visible yet. | Wait and click Controleer records again. |
<records> wijst nog (ook) naar een ander adres. Verwijder dat oude record bij je domeinbeheerder. | An old A/AAAA or CNAME record still exists next to the new one. | Remove the old record. |
We konden <records> nu niet opvragen. Probeer het zo opnieuw. | The DNS lookup failed. A connected domain stays connected. | Try again later. |
Kies eerst hierboven waar de website draait. … | Waar draait de website? is not set, so only the verification record is known. | Choose Op de server van het platform or Bij een eigen host. |
| The certificate does not come through | The domain is proxied by Cloudflare (orange cloud). | Set the records to DNS only (grey cloud). |
| Search engines still show the temporary address | No primary address chosen. | Maak hoofdadres on the right domain; set the Site-URL to it. |
See Domains and DNS.
Forms and statistics
| Symptom | Cause | Fix |
|---|---|---|
Site staat niet live. (404) from submitForm | The production site is offline. Staging sites take forms anyway. | Put the site online in the dashboard. |
KwispleError(400, "bad_request") with field sentences | A declared form did not validate (<Label> is verplicht.). | Show e.message; see Forms. |
Dit moment is net door iemand anders gekozen. (409) | Another submission holds that slot. | Refresh formSlots() and ask for another moment. |
submitForm resolves but nothing is in Formulieren | The honeypot website was filled: the submission is dropped silently. A submission within three seconds of startedAt is kept, but under … berichten mogelijk spam and without a notification. | Send the honeypot's real (empty) value and the moment the form was opened as startedAt. |
| No visitors counted | The site is offline, statistics are off (Bezoekers tellen), the page's origin is not one of the site's (verified domain, platform address or Site-URL), or you are previewing. | Check those; see Statistics and consent. |
Still stuck
- Run
kwisple statusto compare your model with the platform. - Run
kwisple whoamito see which account and dashboard the CLI uses. - Every API error carries
{ error: { code, message } }; the code tells you which table above to read. See Delivery API. - Words you do not know: Glossary.