Skip to content
Back to skills

Dotkernel Troubleshooting

ASecurity

Use when something in a Dotkernel project is not working and the cause is unclear — a route returns 403, 404, 406, 415 or 500 unexpectedly, a service is not found in the container, a handler throws while building a response, config changes have no effect, routes are missing, tests fail in setUp, autoloading fails, a form silently rejects a submit, or CORS preflight fails. Start here before reading code at random.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
databasesgophpbashsqlapidatabasefrontend

Works with

  • cli
  • api

Security analysis

A100/100

Scanned November 7, 2026

npx -y skills add dotkernel/dotboost --skill dotkernel-troubleshooting --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dotkernel Troubleshooting?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Dotkernel Troubleshooting
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/dotkernel-dotkernel-troubleshooting/badge)](https://www.skillsdirectory.com/skills/dotkernel-dotkernel-troubleshooting)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: dotkernel-troubleshooting
description: >
  Use when something in a Dotkernel project is not working and the cause is unclear — a route
  returns 403, 404, 406, 415 or 500 unexpectedly, a service is not found in the container, a
  handler throws while building a response, config changes have no effect, routes are missing,
  tests fail in setUp, autoloading fails, a form silently rejects a submit, or CORS preflight
  fails. Start here before reading code at random.
---

# Symptom → cause

```text
Applies to
  Projects:  - all
  Packages:  - none
```

Work top-down; the first match is usually it.

## 403 / access denied on a route you just added

API: the route name is missing from the RBAC permissions in `authorization.global.php`. Route
names **are** authorization keys. Add it for every role that should reach it, and check the role
hierarchy comment at the top of the file — inheritance direction is not always what people assume.

Admin / Frontend: a *missing* guard entry does not cause a 403 — the guards use `POLICY_ALLOW`,
so an unlisted route is open to everyone. A 403 there means a guard rule exists in
`authorization-guards.global.php` and the caller's role lacks that permission in
`authorization.global.php`. The reverse symptom — a new page reachable while logged out — is
the missing entry.

## 404 on a route you just added

1. The module's `ConfigProvider` is not listed in `config/config.php`.
2. `RoutesDelegator` is not registered as a delegator on `Application::class` in that ConfigProvider.
3. Config cache is stale → run the repo's cache-clear script.
4. Confirm with the route-listing command. Absent → causes 1–3. Present → your URL or method
   differs from what you are calling (API updates are PATCH; templated projects submit POST).

## 404 on an existing route with a valid identifier

The resource-resolution attribute could not find the entity — identifier or placeholder mismatch,
or the record genuinely does not exist.

## "Service not found" / container exception

A missing `factories` entry, or you type-hinted an interface with no `aliases` entry mapping it to
the concrete class. Both live in the module `ConfigProvider`.

## Handler throws while building a response

The handler is missing its delegator registration. In the API that is the handler delegator that
injects the HAL response factory and resource generator — they are not constructor-injected.

## `#[Inject]` appears to be ignored

The class is registered with the wrong factory. It needs `AttributedServiceFactory::class`, not
`InvokableFactory` or a hand-written factory.

## Config change has no effect

Config cache. Also check load order: `*.local.php` overrides `*.global.php`, and the test-local
file overrides both under tests.

## 406 Not Acceptable

The `Accept` header does not match what content negotiation allows for that route.

## 415 Unsupported Media Type

Missing or wrong `Content-Type` on a write request.

## Empty or malformed body on a write

The malformed-body middleware rejected it, or you read the raw stream after the body-params
middleware consumed it. Use `getParsedBody()`.

## A form submit is silently rejected (templated projects)

Missing, stale or unvalidated CSRF token. Check the form has the CSRF element and the handler
validates it. A rotated session invalidates in-flight forms.

## CORS preflight fails

The CORS middleware must be piped **before** the routing middleware, and the origin must be listed
in the CORS local config — which does not exist until you copy it from the `.dist`.

## 403 with a token that "should" work

In stock Dotkernel API a token that fails validation does not produce 401: the authentication
middleware turns any request it cannot authenticate into a guest, so a route not granted to guest
answers 403. Causes: expired token, wrong client id or scope, or the OAuth keys were regenerated
after the token was issued. A 403 that persists with a freshly issued token is an authorization
problem instead — see "403 / access denied on a route you just added" above.

401 comes only from the token-issuing operations, or from a project that pipes Mezzio's own
`AuthenticationMiddleware` instead of the stock one — that middleware answers 401 when
authentication fails. Check which one `config/pipeline.php` or the route's middleware list uses.

## Class not found after adding a namespace

`composer dump-autoload`, then check the PSR-4 mapping. Case-sensitive, even where the local
filesystem is not.

## Tests fail in `setUp()`

- *"test mode is NOT enabled"* → the test-local config file is missing.
- *"non in-memory database"* → present but not configured for memory. Do not repoint tests at a
  real database.
- Column type errors only under test → an enum DBAL type with no SQLite branch.

## Schema-validation CI job is red

Entities and migrations have drifted. Generate a migration; do not edit the entity to match an old
migration, and do not hand-edit the migration.

## Passes locally, fails in CI (or the reverse)

A different PHP version in the matrix, or a stale local `.phpcs-cache` / `.phpunit.result.cache`.

## Diagnostic commands

All read-only except `composer clear-config-cache`, which deletes the cached merged config — safe,
and it touches no committed file, but it is a write.

```bash
php bin/cli.php route:list          # API / Admin; or the repo's equivalent
php bin/cli.php                     # console commands — API, Admin, Queue (no bin/cli.php in Frontend or Light)
composer clear-config-cache
php -l <file>
composer cs-check
composer static-analysis
php ./vendor/bin/doctrine-migrations status
php ./bin/doctrine fixtures:list
```

If nothing above matches, say so and ask. Do not start editing config files to see what happens.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.