Troubleshooting
Start with the failing request in your browser’s Network panel and the
[caretcms] messages in your server logs. Preserve unsaved text before reloading,
signing out, discarding drafts, or changing storage.
Login or API returns 404
Section titled “Login or API returns 404”A production static build intentionally contains no admin or API routes. Author
in astro dev, or use a separately deployed authoring server. delivery: 'auto'
already detects Astro’s static output; delivery: 'static' makes that choice
explicit. See Static delivery.
For server delivery, check your Astro host adapter and configured mountPath
and apiBasePath (defaults /admin and /api/cms). enableAdmin: false hides
the admin interface; it does not disable authenticated CMS API routes. Also
check for your own routes overlapping the CMS paths.
Signed in but nothing is editable
Section titled “Signed in but nothing is editable”- Confirm
/api/cms/auth/sessionreturnsauthenticated: true. - Check that the page has a valid
data-caretbinding or supporteddata-caret-mdprose. The signed-in empty-page hint means no editable fields were found. - Switch from Preview to Edit and ensure
enableInlineEditoris notfalse. - Check
/__caret/editor.jsloads successfully and inspect console errors.
Bindings need a full collection::id::field or a field inside an ancestor
data-caret-scope="collection::id". See Inline editing.
Authentication or permission failure
Section titled “Authentication or permission failure”| Response | What to check |
|---|---|
| 401 on save | Session expired or missing; preserve local edits, then sign in again |
| 403, missing request header | Custom mutation clients need x-caret-request: 1 |
| 403, policy denial | Your identity adapter’s authorize() decision for this action and collection |
| 409 on password login | An external identity provider is authoritative; use its login flow |
| Session rejected after login | Stable CARET_SESSION_SECRET, matching across instances; cookie forwarding and HTTPS |
Production password authentication requires configured credentials and a stable
session secret; it fails closed when required secrets are missing. Check that
variables are present, without printing secret values. The prefixed
CARET_EDIT_PASSWORD takes precedence over legacy EDIT_PASSWORD. Check for
accidental whitespace in your secret manager.
If your local .env password is ignored or the login page still says a temporary
password is active, stop the dev server and run
node --env-file=.env ./node_modules/astro/bin/astro.mjs dev. CaretCMS needs process/runtime environment
variables; simply placing a file beside the project does not ensure that those
variables are loaded into its server process.
See Authentication and Permissions.
Saved changes are not public
Section titled “Saved changes are not public”First identify the status, rather than repeatedly saving:
- Saved draft: Publish from the editor that owns the draft.
- Published on a static site: Rebuild with access to the updated content, then deploy the resulting HTML and uploads.
- Deploy requested: A successful webhook means accepted, not live. Check provider evidence or your deployment service.
- Server delivery: Ensure the page is rendered on request and your cache has been invalidated. Policy-controlled edits remain drafts until publication.
- Markdown body: Prose edits always need Publish, even on a server site.
A boolean publication field may also hide an entry from public Caret reads. See Saving and publishing and Deployment status.
A local page reload shows old text
Section titled “A local page reload shows old text”If a static page in astro dev shows its template or published text after a
reload, open the entry in Studio using the same signed-in session. Check the
saved field value there before retyping or discarding anything. The on-page
preview and persisted draft are separate checks.
Once Studio confirms the draft, Publish and rebuild. Verify the result with
npm run preview, which serves the generated public HTML. If the draft itself
is missing in Studio, investigate the save request, session, and storage path.
Conflict or interrupted publication
Section titled “Conflict or interrupted publication”| Error or symptom | Recovery |
|---|---|
| Revision conflict (409) | Preserve your edits, read the latest revision, compare, then reapply your intended change |
stale_entry |
Published data changed since the draft started; preserve the draft before discarding and rebuilding it |
stale_body |
Markdown source ranges changed; preserve edits, reload the current source, and reapply |
legacy_draft |
An older structured draft lacks a tracked baseline; preserve it and recreate against current content |
recovery_conflict |
Keep the recovery plan; an operator must reconcile storage before retrying |
| Rebuild failed or timed out | Content may already be published; use Retry deploy or your deployment service |
Do not interpret HTTP 200 from a bulk publish as every entry succeeding. Inspect
published, conflicts, and failed. An interrupted entry may already have
changed base content. See Publish recovery.
Validation or unexpected Studio fields
Section titled “Validation or unexpected Studio fields”Check /api/cms/schema?collection=your-collection: source identifies the
registered, dynamic, or inferred schema being used. Registered collection names
must match exactly. An empty inferred collection has no useful shape; register
an explicit schema or add representative data. Dynamic collections are created
through the API, not a Studio schema-builder form.
For invalid stored data, repair the fields named in the validation issues. The live loader skips invalid entries when reading a collection and returns an error for an invalid single entry. Studio date formats use string inputs; there is no dedicated date picker. See Schemas.
Edits disappear after redeploy
Section titled “Edits disappear after redeploy”Filesystem storage needs persistent content, metadata/history, draft overlays,
and uploads. Keeping only .caret/data is insufficient. Use a persistent volume
and backups, or a storage adapter designed for your host.
For concurrent Cloudflare writers, use the Durable Object adapter. KV’s eventual consistency does not solve concurrent-write conflicts. Filesystem and Markdown deployments must use one writer process.
Upload fails or image is broken
Section titled “Upload fails or image is broken”- Check the response’s validation error and supported image type/size.
- For R2, configure
publicBaseUrlorR2_PUBLIC_DOMAINwith an enabled public custom/r2.devhostname. Test the returned URL while signed out. - For local uploads, ensure the uploaded files are persisted and included in static deployment artifacts.
- Alt text is a separate Studio field; the inline image picker only changes the image URL.
Studio is slow or live content is stale
Section titled “Studio is slow or live content is stale”Studio uses paginated requests (24 entries by default, maximum 100) and search. A storage adapter may still load its whole collection before those results are sliced. For larger data sets, measure adapter reads and consider a dedicated query layer.
Live collections read storage at render time. If you configure caching, bypass it for authenticated/private-preview responses and invalidate public pages after publication. Cache tags alone do not configure your CDN.
Report an issue
Section titled “Report an issue”Include your package versions, host/delivery mode, a redacted config, reproduction steps, and the relevant response/error. Remove credentials, cookies, private content, and authorization headers before sharing at GitHub issues.