---
name: troubleshooting-and-debugging
description: Diagnose common tibi website-project failures. Covers config loading, auth and permission mistakes, hook/goja errors, upload and CORS issues, and a practical debugging order so later agents do not thrash across unrelated layers.
---

# troubleshooting-and-debugging

## When to use this skill

Use this skill when:

- a tibi project is failing in a way that is not obviously tied to one file
- hooks, config, permissions, uploads, or routing behave unexpectedly
- a project worked before and now fails after configuration or integration changes
- you need a practical debugging order instead of ad-hoc guessing

## Goal

Help later agents debug the stack systematically.

The main value of this skill is not “more tips”. It is the order of operations: isolate the failing layer first, then inspect the right tool surface for that layer.

## Source of truth

Use these sources when debugging:

- `tibi-server/docs/15-troubleshooting.md`
- `tibi-server/docs/06-hooks.md`
- `tibi-server/docs/05-authentication.md`
- `tibi-server/docs/17-field-level-permissions.md`
- `tibi-server/internal/models/eval_context.go` when hook API exposure is in doubt
- `tibi-server/internal/hook/context_*.go` when helper registration is in doubt
- `.agents/skills/tibi-hook-authoring/SKILL.md`
- `.agents/skills/security-hardening-and-token-strategy/SKILL.md`
- `.agents/skills/tibi-ssr-caching/SKILL.md`

## Debugging order

Start in this order unless a more specific failure anchor already exists:

1. reachability and environment
2. auth/token/permission layer
3. config loading and YAML shape
4. hook/goja behavior
5. uploads/media pathing
6. SSR/routing/publication behavior
7. CORS or browser-integration issues

This order prevents chasing frontend symptoms when the real issue is project registration, token scope, or a broken config reload.

## Layer 1 — Reachability and environment

Check first:

- website URL responds
- admin URL responds
- API responds with JSON where expected
- Docker services are actually up

If `/api/...` returns HTML, do not debug application logic yet. Fix the environment/proxy path first.

## Layer 2 — Auth and permission mistakes

Common patterns:

- `401 Unauthorized` → missing/invalid JWT or wrong auth surface
- `403 Forbidden` → collection/action permissions wrong, user not assigned correctly, or token permission mismatch
- static `Token` works for one surface but not another → wrong header type for the requested operation

Check:

- `X-Auth-Token` vs `Token` vs `X-Admin-Token`
- collection/action permissions
- project/user assignment
- field-level readonly/hidden behavior if writes fail unexpectedly

Important current note:

- current upstream troubleshooting and auth docs still describe MD5-managed passwords; do not debug login failures by assuming the active username/password flow has already moved to bcrypt

## Layer 3 — Config and reload problems

Common patterns:

- project not loading after config change
- env vars not resolving
- CORS behaving differently than expected

Check:

- YAML syntax
- whether the correct config file is being loaded
- whether project reload actually ran
- whether env placeholders use `${VAR_NAME}` format

When the problem smells like “the server ignores my config change”, verify reload and active config path before editing more files.

## Layer 4 — Hook and goja errors

Common patterns:

- `require is not defined`
- `async`/`await` assumptions in hooks
- wrong context object assumptions
- timeouts or infinite loops

Remember:

- hooks run in goja, not Node.js
- no `require()` or npm runtime
- no normal async/await model
- hook behavior often depends on the exact lifecycle step
- tibi hook surfaces are accessed through `context`, including request and registered packages such as `context.request()`, `context.db.find()`, `context.http.fetch()`, `context.smtp.sendMail()`, `context.debug.dump()`, or `context.exec.command()`

Use the hook skill for step-specific quirks such as `context.data` timing or `context.filter` behavior.

## Layer 5 — Upload and media failures

Common patterns:

- files not being saved
- media URLs render incorrectly
- image filters return 404

Check:

- collection `uploadPath`
- file field type
- base64/data-URI or multipart expectations
- filter names in collection config
- whether frontend/admin preview code expects `_lookup` or raw IDs

## Layer 6 — SSR, routing, and publication failures

Common patterns:

- route works in browser but not in SSR
- SSR returns empty page or wrong status
- unpublished or inactive entries disappear unexpectedly

Check:

- route model and language-prefix handling
- `ssrValidatePath()`
- `publishedFilter`
- lookup usage for page-critical relations
- cache invalidation after mutations

Do not debug SSR only through browser navigation. Use the SSR endpoint directly when the failure is SSR-shaped.

## Layer 7 — Browser integration and CORS

Common patterns:

- browser form fails while direct API call works
- preflight fails
- credentials or auth headers do not cross origins correctly

Check:

- which layer owns CORS config
- `allowOrigins`, `allowMethods`, `allowHeaders`, `allowCredentials`
- whether the real deployment even needs cross-origin calls

## Useful debugging tools

### Hook-side debug helpers

```js
context.debug.dump(context.data, "payload")
context.debug.dump(context.request().header("Authorization"), "auth-header")
```

### Request inspection

```js
const req = context.request()
context.debug.dump({
    method: req.method,
    path: req.path,
    url: req.url,
    host: req.host,
    clientIp: req.clientIp,
})
```

### Database inspection from hooks

```js
const rows = context.db.find("content", { limit: 5 })
context.debug.dump(rows, "sample-content")
```

### Direct endpoint debugging

Prefer targeted `curl` probes for:

- API JSON responses
- SSR endpoint behavior
- auth header behavior
- audit endpoint behavior when relevant

## Anti-patterns

- jumping between frontend, hooks, and config without isolating the failing layer
- assuming a browser symptom proves a frontend bug
- trying to fix permissions only in the UI
- debugging SSR without the SSR endpoint
- relying on outdated assumptions from old stack behavior

## What an LLM should inspect first

When asked to debug a tibi project with unclear failure ownership, inspect in this order:

1. current failing command or URL
2. environment reachability
3. auth/permission boundary
4. config/reload state
5. hook/runtime layer
6. SSR/publication layer if the failure is page-related

This keeps debugging local and falsifiable instead of turning into broad repo wandering.
