KoniKode · Software built with intention

KNOWLEDGE BASE

Documentation

DOCUMENTATION
CURRENT APPLICATIONClean Framework
DocumentationClean Framework

Clean Framework · DOCUMENTATION

Safe local troubleshooting

Safe local troubleshooting

Bounded candidate reference — 2026-10-20: 0.2.0-rc.1 is committed locally through 84f415b3098af5653577b2c65eea31fca21df79c, unpublished and not production-approved; stable PHP >=8.5.11 <8.6.0 is required. This is documentation, not adoption: this knowledge base retains its installed 0.1.0-rc.1 dependency and PHP 8.2.11 local profile. Dated PHP 8.2 evidence is historical; earlier dirty-source reports retain their original test provenance, not retroactive clean-commit proof. Candidate examples are illustrative: API signatures were reviewed, but candidate code was not executed by this editorial update. See current checkpoint, open criteria and adoption boundary.

First distinguish this KB runtime from the new candidate. PHP 8.2 cannot boot 0.2.0-rc.1; never bypass the guard. See PHP 8.5 migration.

Start in the consuming application's directory, not public/. Record the selected environment, release, URL, status, and opaque error reference. Read the application/server log only in a system you are authorized to inspect. Do not paste secrets, cookies, request bodies, or complete configuration into chat, tickets, or logs. These checks do not authorize production access.

Startup failure or HTTP 500

  • Confirm vendor/autoload.php exists and the Composer path dependency points to the intended Clean Framework checkout/version. Use `composer validate --strict --no-check-publish` before installing missing dependencies locally.
  • Select APP_ENV explicitly. Missing/unknown environments, invalid typed settings, schema failures, and missing required secrets fail before boot.
  • For a copied skeleton, run APP_ENV=TEST php bin/console config:check. It reports key names and counts, never secret values. The reading-list example has no console; exercise its loader/front controller or tests instead.
  • Match the response's opaque reference to the exception class and safe file/ line metadata in private logs. The intentionally redacted log may not contain the exception message; reproduce with local fixtures if needed.
  • Check readable view roots and writable private runtime directories. Avoid blanket permissions such as 0777; use the intended PHP worker ownership.
  • Check for accidental echo, debug dumps, whitespace before <?php, or a UTF-8 BOM in bootstrap/composition. Returning a Response is not sending it.

Do not expose stack traces or enable production display_errors to diagnose a failure. A generic 500 does not establish a database or router fault on its own.

Environment changes do not take effect

Runtime variables beat .env; the selected prefix such as TEST_ beats a generic variable. Check deployment configuration without printing values. APP_ENV=TEST php ... overrides an inherited selection for that invocation. .env parsing does not call putenv(). Restart an existing PHP development server or worker after changing its process environment, then check the new environment through a safe diagnostic. DEV, TEST, STAGE, and PROD have separate overlays; changing one does not change another.

See CONFIGURATION.md for bindings and precedence.

HTTP 404, 405, redirect, or wrong route

  • A framework 404 may mean no route matched or a controller deliberately concealed a missing/denied object. Inspect the registered route and object policy before changing filesystem rules.
  • A 405 means the path matched but not the effective method. Check GET/POST registration, the original method, and any allowed method override.
  • Declare specific routes before parameter/catch-all routes. Constraints validate shape, not a database record's existence.
  • Configure the same base path on the request and router. Generate named URLs rather than hard-coding deployment prefixes.
  • Review normalize, redirect_safe, or strict canonical-path policy if a trailing slash or alternate encoding redirects or is rejected.
  • Start PHP locally with -t public public/dev-router.php. Under Apache, the public DocumentRoot, enabled rewrite module, and permitted .htaccess overrides require isolated host verification. A built-in server pass is not proof that Apache rewrites work.

See ROUTING_AND_MIDDLEWARE.md and CLI_AND_OPERATIONS.md.

HTTP 401, 403, or protected-file 404

Check middleware order, the configured authenticator, current session/account state, exact permissions/scopes, recent authentication, and object policy. Use RequestAttribute::PRINCIPAL, not 'principal', to read the identity. Opaque file names are not authorization. Do not bypass policy or move files under public/ as a fix. Machine credentials additionally require the correct environment, lifecycle, and scopes; never log an Authorization header.

HTTP 419: missing or expired CSRF proof

Obtain a current token from the same session and supply the configured form field or X-CSRF-Token header on unsafe requests. Identity/privilege changes rotate both session and CSRF proof; refresh stale forms after login. Check cookie host/path/SameSite settings and whether a Secure cookie can be sent on the development connection. Do not weaken production cookie settings or globally exempt routes. Signed provider webhooks need their own explicitly registered verification/exemption policy.

See AUTHENTICATION_AND_SECURITY.md.

HTTP 400, 413, 415, or 406

Check the request's method, Content-Type, Accept, JSON syntax/depth, body bytes, upload count/size, and route-specific ceilings. Query/form/body inputs are distinct; a client JSON request does not populate PHP's ordinary form fields. The server, PHP, framework, and route may enforce different size limits; the earliest rejection wins. Negotiation middleware can reject unsupported input or output types. Do not increase all limits simply to suppress the status.

A view fails or renders unexpected output

Check the exact .php view name, readable configured root, and valid variable keys. Traversal/symlink escape is denied. Application data overrides shared values; matching composers run in registration order and must return arrays. Use trusted application-selected partial names, $e for HTML, and an escaping helper appropriate to other output contexts. Never fix a template with eval or by accepting user-selected filesystem paths.

See VIEWS.md and the walkthrough.

CSS, JavaScript, or images do not load

  • Inspect the actual generated URL, response status, and Content-Type. HTML returned for a stylesheet usually indicates a path/routing mismatch.
  • Confirm case-sensitive filenames, public prefix/base path, source-root containment, and that the deployed source file actually exists.
  • CSS/JS use static files and are minified at build time. A fingerprint query is cache busting, not an Apache no-store policy.
  • Generated images need an application route wired to AssetController, valid dimensions/options, GD format support, and writable private cache/ lock directories. Merely calling url() does not register a route.
  • When cache is disabled, check actual HTTP headers and the browser's request rather than assuming a URL option controls server or service-worker caching.

Assets are public and do not provide hotlink or private-file protection. See ASSETS.md.

Console command missing, locked, or unhealthy

Run the consuming application's php bin/console list; supplied framework classes are not automatically registered. A lock refusal is not permission to delete another worker's lock. Confirm ownership/TTL and the selected adapter. Exit 2 means usage, 3 lock denial, and 4 unavailable environment. Health probes may contact the configured database/provider; do not run health:check merely because it is called read-only. The skeleton's database probe requires an authorized isolated database. config:check does not run that probe.

OAuth callback rejected

Check exact provider/environment metadata, callback URI, browser-session state, expiry, and single-use consumption. SessionManager uses get()/remove(). Do not use query-only state as expected state, replay a consumed code, or log state/verifiers/tokens. The simple guide supports one outstanding browser flow; parallel flows need application-owned keyed state. Restart a rejected flow.

Before escalating

Record only: framework/application release, PHP version, selected environment, safe status/category, opaque reference, reproduction steps using dummy input, and the local checks already run. State separately which deployment checks are still TO VERIFY. Do not attach secrets, private files, backups, or full logs.

Editorial provenance

Source: docs/TROUBLESHOOTING.md. Source SHA-256: 07e63cf78c2dbfa69a0a08e4d4e1d288b45c2acf07e7b16c0bfbd682d3eed32c.

Framework candidate reference; editorial checkpoint 2026-10-20. See candidate status and adoption boundary.

EXPLORE FURTHER

Drag a divider or use Left and Right Arrow keys to resize. Hold Shift for larger steps. Enter hides or restores the sidebar; Home and End select its minimum or maximum width. Double-click resets the width.

Install KoniKode