Skip to main content

Introduction

laravel/doctor is the official package for diagnosing common configuration, environment, and infrastructure issues in a Laravel application. v0.1.0 was released on July 28, 2026. Each diagnostic is a single check. For example, “can Laravel write to the storage directory?” is checked and one of several statuses is reported. When a fix is safe and deterministic, an automatic fix is offered; when an issue can’t be repaired automatically (a broken asset build, say), remediation steps are shown instead.

Running it

After installation, the doctor Artisan command is registered.
When it finds a fixable problem, Doctor reports the issue and asks whether to apply the fix.
Use the --fix option to apply fixes without confirmation.
The built-in fixes cover deterministic local repairs — creating .env, generating APP_KEY, disabling debug mode in production, adding .env to .gitignore, creating storage:link, and repairing write permissions on storage directories.
The fix functionality is available only in the CLI and agent output formats. In the JSON and GitHub report formats, --fix is rejected so that machine-readable reports don’t modify the application.
Use --bail to stop execution at the first diagnostic that fails or errors.

Diagnostic statuses

Each diagnostic returns one of the following statuses. By default, the command exits with a failure status when there is a fail or error. Use --fail-on=warn to also fail on warnings, or --fail-on=never to only report issues.

Selecting diagnostics

You can select or exclude diagnostics by class name, group, package, or a package wildcard.
Publish the configuration file to configure persistent selections.

Environment modes

The sync queue is a reasonable default during local development, but in production it means queued jobs run synchronously inside a web request. To make judgments like this, Doctor resolves your application into one of two modes: local or production. Laravel’s standard environment names (local, production, staging) are recognized automatically. If you use other names, group them into modes in the configuration file.

Built-in diagnostics

Doctor ships with a suite of built-in diagnostics that includes:
  • Environment.env presence, APP_KEY, PHP version, required extensions, timezone
  • Composer — dependency install state, autoload optimization, auto-repair of composer.lock
  • Configuration — whether the config files load and cache, required values for the drivers you have enabled
  • Database — reachability of connections, existence of SQLite files, automatic application of pending migrations
  • Cache, queue, scheduler, session — reachability of configured drivers, detection of the sync queue outside of production
  • Storage — reachability of the default disk, write permissions on required directories, existence of storage:link
  • Security — consistency between debug mode and environment, .env being present in .gitignore, audit of Composer dependencies

Writing your own diagnostics

You can create your own diagnostic class by extending Laravel\Doctor\Diagnostic and implementing the check() method. You can also scaffold one with the make:diagnostic Artisan command.
Below is an example of a diagnostic that checks whether APP_KEY is configured and generates it automatically when it isn’t.
When a fix has multiple sensible options, declare them with fixOptions(). The CLI will present them as a picklist, and the value that’s chosen is passed to fix().
A “don’t fix” option is always appended to the picklist (the default is Skip — leave unfixed). When a phrase that keeps the current selection is clearer, specify a decline label.

Diagnostic helpers

Many applications and packages end up writing the same kinds of checks over and over, so Doctor provides helpers in the Laravel\Doctor\Support namespace for common patterns. The Configured helper reads configuration values defensively. Since a diagnostic must be able to inspect an app whose configuration is broken without throwing before it can report, these methods differ from the typed accessors on the config repository: they don’t throw when they encounter unexpected types.
The ActiveDrivers helper resolves wrapper drivers — such as a default log channel of stack or a failover mailer — into the concrete channels or mailers that will actually be used.
The Details helper formats evidence to attach to withDetails(). Details::bullets() renders a list of strings as bullets, Details::failures() renders keyed failure messages, and Details::processOutput() picks the most useful output stream from a completed process.
Packages register diagnostics from a service provider with the same API.
Reports show which package provided each diagnostic.

Running programmatically

You can also invoke Doctor::run() directly, without going through the Artisan command.
To also apply fixes when running programmatically, set fixUsing. The callback receives each failed diagnostic that provides a fix, and can return false to skip, true to apply the standard fix, or a fix option value to apply that specific choice. When a fix is applied, Doctor re-runs the diagnostic so it’s reflected in the report.

Output formats and AI agent support

By default Doctor produces a readable CLI report, but you can also choose JSON or the GitHub Actions annotation format.
When it detects that it’s running inside an AI coding agent such as Claude Code or Cursor via Laravel Agent Detector, the default becomes an agent-optimized format that follows the same convention as Laravel PAO.
Any issue with fixable: true can be repaired by re-running with --fix. To try this format outside of an agent, run AI_AGENT=test php artisan doctor.

Wrap-up

laravel/doctor lets you quickly surface configuration, environment, and infrastructure problems with a single php artisan doctor run. It plays nicely with AI coding agents by producing output in the same convention as Laravel PAO, making it worth considering for CI/CD or automated agent-driven repair workflows.

laravel/doctor repository

Source code and the latest updates.
Last modified on August 2, 2026