Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mago Laravel Package

carthage-software/mago

Mago is an extremely fast PHP linter, formatter, and static analyzer written in Rust. It brings Rust-inspired speed and reliability to PHP projects with a modern toolchain and great developer experience, plus multiple install options (script, Homebrew, Composer).

View on GitHub
Deep Wiki
Context7

title: Analyzer configuration Reference

Configuration reference

Mago's analyzer is highly configurable, allowing you to tailor the analysis to your project's specific needs. All settings go under the [analyzer] table in your mago.toml file.

[analyzer]
# Ignore a specific error code across the whole project
ignore = ["mixed-argument"]

# Ignore an error code only in specific paths
ignore = [
  "mixed-argument",
  { code = "missing-return-type", in = "tests/" },
]

# Use a baseline file to ignore existing issues
baseline = "analyzer-baseline.toml"

General options

Option Type Default Description
excludes string[] [] A list of paths or glob patterns to exclude from analysis.
ignore (string | object)[] [] Issue codes to ignore, optionally scoped to specific paths. See Path-scoped ignoring.
baseline string null Path to a baseline file to ignore listed issues. When specified, the analyzer will use this file as the default baseline, eliminating the need to pass --baseline on every run. Command-line --baseline arguments will override this setting.
baseline-variant string "loose" The baseline format variant to use when generating new baselines. Options: "loose" (count-based, resilient to line changes) or "strict" (exact line matching). See Baseline Variants for details.
minimum-fail-level string "error" Set the minimum issue severity that causes the command to exit with a non-zero status. Options: "note", "help", "warning", "error". Can be overridden by the --minimum-fail-level CLI flag.

:::tip Tool-Specific Excludes The excludes option here is additive to the global source.excludes defined in the [source] section of your configuration. Files excluded globally will always be excluded from analysis, and this option allows you to exclude additional files from the analyzer specifically.

For example:

[source]
excludes = ["cache/**"]  # Excluded from ALL tools

[analyzer]
excludes = ["tests/**/*.php"]  # Additionally excluded from analyzer only

:::

Path-scoped ignoring

The ignore option accepts three formats:

Plain string — ignore a code everywhere:

ignore = ["missing-return-type"]

Object with single path — ignore a code only in a specific directory or file:

ignore = [
  { code = "missing-return-type", in = "tests/" },
]

Object with multiple paths — ignore a code in several locations:

ignore = [
  { code = "missing-return-type", in = ["tests/", "src/Legacy/"] },
]

All three formats can be mixed in the same ignore list:

ignore = [
  "mixed-argument",
  { code = "missing-return-type", in = "tests/" },
  { code = "unused-parameter", in = ["tests/", "src/Generated/"] },
]

Paths are matched as prefixes against relative file paths from the project root. Both "tests" and "tests/" will match all files under the tests directory.

:::tip Path-scoped ignoring is different from excludes:

  • excludes removes files from analysis entirely — they won't be parsed for type information.
  • ignore with in still analyzes the files but suppresses specific issue codes in the output. :::

Feature flags

These flags control specific, powerful analysis capabilities.

Option Default Description
find-unused-expressions true Find and report expressions whose results are not used (e.g., $a + $b;).
find-unused-definitions true Find and report unused definitions (e.g., private methods that are never called).
analyze-dead-code false Analyze code that appears to be unreachable.
memoize-properties true Track the literal values of class properties. Improves type inference but may increase memory usage.
allow-possibly-undefined-array-keys true Allow accessing array keys that may not be defined without reporting an issue.
check-throws false Check for unhandled thrown exceptions that are not caught or documented with [@throws](https://github.com/throws).
check-missing-override false Check for missing #[Override] attributes on overriding methods (PHP 8.3+).
find-unused-parameters false Find and report unused function/method parameters.
strict-list-index-checks false When true, requires any integer used as a list index to be provably non-negative.
no-boolean-literal-comparison false When true, disallows direct comparison to boolean literals (e.g., $a === true).
check-missing-type-hints false When true, reports missing type hints on parameters, properties, and return types.
check-closure-missing-type-hints false When true, checks closures for missing type hints when check-missing-type-hints is enabled.
check-arrow-function-missing-type-hints false When true, checks arrow functions for missing type hints when check-missing-type-hints is enabled.
register-super-globals true Automatically register PHP superglobals (e.g., $_GET, $_POST) for analysis.
trust-existence-checks true When true, narrows types based on method_exists(), property_exists(), function_exists(), and defined() checks.
check-property-initialization false When true, checks that typed properties are initialized in constructors or class initializers.
check-use-statements false When true, reports use statements that import non-existent classes, functions, or constants.
check-name-casing false When true, reports incorrect casing when referencing classes, functions, etc. (e.g., new fooBar() when defined as FooBar). Helps prevent autoloading failures on case-sensitive file systems.
enforce-class-finality false When true, reports classes that are not final, abstract, or annotated with [@api](https://github.com/api) and have no children.
require-api-or-internal false When true, requires abstract classes, interfaces, and traits to have [@api](https://github.com/api) or [@internal](https://github.com/internal) annotations.
check-experimental false When true, reports usage of classes, interfaces, traits, and functions marked with [@experimental](https://github.com/experimental) from non-experimental contexts.
allow-side-effects-in-conditions true When false, reports calls to impure functions (not marked [@pure](https://github.com/pure) or [@mutation-free](https://github.com/mutation-free)) inside if, while, for, ternary, or match conditions. Helps catch surprising evaluation-order bugs.

Property initialization

These options control how the analyzer checks property initialization.

Option Type Default Description
check-property-initialization bool false Enable/disable property initialization checking entirely.
class-initializers string[] [] Method names treated as class initializers (like __construct).

How it works

When check-property-initialization is enabled, the analyzer reports:

  • missing-constructor: Classes with typed properties that have no constructor to initialize them
  • uninitialized-property: Typed properties not initialized in the constructor

The class-initializers setting allows you to specify additional methods that should be treated as initializers. Properties initialized in these methods count as "definitely initialized", just like in __construct. This is useful for frameworks that use lifecycle methods like:

  • PHPUnit's setUp() method for test classes
  • Framework-specific boot() or initialize() methods

Example

[analyzer]
# Treat setUp as a class initializer (for PHPUnit tests)
class-initializers = ["setUp", "initialize", "boot"]

With this configuration, the following code won't trigger false positives:

class MyTest extends TestCase
{
    private string $name;

    protected function setUp(): void
    {
        // Property initialized in setUp - no error reported
        $this->name = "test";
    }
}

Enabling property initialization checks

Property initialization checking is disabled by default. To enable it:

[analyzer]
check-property-initialization = true

This enables both missing-constructor and uninitialized-property issues.

Exception filtering

When check-throws is enabled, you can fine-tune which exceptions should be ignored using these options:

Option Type Default Description
unchecked-exceptions string[] [] Exceptions to ignore including all their subclasses (hierarchy-aware).
unchecked-exception-classes string[] [] Exceptions to ignore only as exact class matches (not subclasses or parent classes).

How it works

  • unchecked-exceptions: When you add an exception class here, that exception and all classes that extend it will be ignored. This is useful for ignoring entire exception hierarchies, like all logic exceptions.

  • unchecked-exception-classes: When you add an exception class here, only that exact class is ignored. Subclasses and parent classes are still checked. This is useful when you want to ignore a specific exception without affecting related exceptions.

Example

[analyzer]
check-throws = true

# Ignore LogicException and ALL its subclasses:
# - InvalidArgumentException
# - OutOfRangeException
# - DomainException
# - etc.
unchecked-exceptions = [
    "LogicException",
    "Psl\\Type\\Exception\\ExceptionInterface",
]

# Ignore ONLY this specific exception class (not its parent or child classes)
unchecked-exception-classes = [
    "Psl\\File\\Exception\\FileNotFoundException",
]

In this example:

  • Any unhandled LogicException or its subclasses (like InvalidArgumentException) won't be reported
  • Any class implementing Psl\Type\Exception\ExceptionInterface won't be reported
  • Only the exact Psl\File\Exception\FileNotFoundException is ignored, but other file exceptions would still be reported

:::tip When to use which option Use unchecked-exceptions when you want to ignore an entire category of exceptions, such as logic errors that indicate programming mistakes rather than runtime issues.

Use unchecked-exception-classes when you want to ignore a specific exception but still want to track its parent or sibling exceptions. :::

Experimental API detection

When check-experimental is enabled, the analyzer reports warnings when code marked with [@experimental](https://github.com/experimental) is used from a non-experimental context. This helps teams manage unstable APIs that may change or be removed without notice. Available since Mago 1.19.0.

How it works

Mark classes, interfaces, traits, or functions with the [@experimental](https://github.com/experimental) PHPDoc tag:

/** [@experimental](https://github.com/experimental) */
class UnstableApi {
    public function doSomething(): void {}
}

/** [@experimental](https://github.com/experimental) */
function beta_feature(): void {}

The analyzer will then warn when these symbols are used from non-experimental code:

// Warning: Usage of experimental class-like `UnstableApi`.
new UnstableApi();

// Warning: Usage of experimental function `beta_feature`.
beta_feature();

// Warning: Usage of experimental class-like `UnstableApi`.
class MyService extends UnstableApi {}

Suppressing warnings

Usage from an experimental context is allowed without warnings:

/** [@experimental](https://github.com/experimental) */
function also_experimental(): void {
    // OK — both caller and callee are experimental
    new UnstableApi();
    beta_feature();
}

/** [@experimental](https://github.com/experimental) */
class ExperimentalConsumer extends UnstableApi {
    // OK — the class itself is experimental
}

class StableService {
    /** [@experimental](https://github.com/experimental) */
    public function experimentalMethod(): void {
        // OK — the method is experimental
        new UnstableApi();
    }
}

Enabling experimental checks

[analyzer]
check-experimental = true

Plugins

Plugins extend the analyzer with specialized type information for libraries and frameworks. They provide accurate type inference for functions that would otherwise return generic types.

Option Type Default Description
disable-default-plugins bool false Disable all default plugins. Only explicitly listed plugins will be used.
plugins string[] [] List of plugins to enable (by name or alias).

Available plugins

Plugin ID Aliases Default Description
stdlib standard, std, php-stdlib Enabled Type providers for PHP built-in functions (strlen, array_*, json_*, etc.)
psl php-standard-library, azjezz-psl Disabled Type providers for php-standard-library package
flow-php flow, flow-etl Disabled Type providers for flow-php/etl package
psr-container psr-11 Disabled Type providers for psr/container package

How plugins work

Plugins provide "type providers" that give the analyzer precise type information for library functions. For example, the stdlib plugin knows that:

  • array_filter($array) returns the same array type but potentially with fewer elements
  • json_decode($json, true) returns array<string, mixed> when the second argument is true
  • strlen($string) returns int<0, max>

Without plugins, these functions would return less precise types like mixed or array.

Example configurations

Using default plugins only

By default, the stdlib plugin is enabled:

[analyzer]
# No configuration needed - stdlib is enabled by default

Enabling additional plugins

[analyzer]
plugins = ["psl", "flow-php", "psr-container"]

Disabling all plugins

[analyzer]
disable-default-plugins = true

Using only specific plugins

[analyzer]
disable-default-plugins = true
plugins = ["psl"]  # Only enable PSL, not stdlib

:::tip Plugin aliases You can use any of the plugin aliases for convenience. For example, plugins = ["std"] is equivalent to plugins = ["stdlib"]. :::

Strict mode

The analyzer can be configured to be more or less strict depending on your project's needs. This section describes how to configure the analyzer for maximum strictness.

Maximum strictness configuration

For the strictest possible analysis, use the following configuration:

[analyzer]
# Enable all checks
find-unused-expressions = true
find-unused-definitions = true
analyze-dead-code = true
check-throws = true
check-missing-override = true
find-unused-parameters = true
check-missing-type-hints = true
check-closure-missing-type-hints = true
check-arrow-function-missing-type-hints = true
enforce-class-finality = true
require-api-or-internal = true
check-experimental = true

# Enable strict checks
strict-list-index-checks = true
no-boolean-literal-comparison = true

# Disable lenient behaviors
allow-possibly-undefined-array-keys = false
trust-existence-checks = false

Strictness options explained

Type hint enforcement

Option Strict Value Effect
check-missing-type-hints true Reports missing type hints on function parameters, return types, and class properties.
check-closure-missing-type-hints true Also checks closures for missing type hints (requires check-missing-type-hints).
check-arrow-function-missing-type-hints true Also checks arrow functions for missing type hints (requires check-missing-type-hints).

Array access strictness

Option Strict Value Effect
allow-possibly-undefined-array-keys false Reports errors when accessing array keys that may not exist.
strict-list-index-checks true Requires list indices to be provably non-negative (int<0, max>).

Runtime check behavior

Option Strict Value Effect
trust-existence-checks false Ignores method_exists(), property_exists() checks; requires explicit type hints.

When trust-existence-checks is enabled (the default), the analyzer narrows types based on runtime existence checks:

function process(object $obj): mixed
{
    // With trust-existence-checks = true (default):
    // No warning - method existence is verified at runtime
    if (method_exists($obj, 'toArray')) {
        return $obj->toArray();
    }

    // With trust-existence-checks = false:
    // Warning reported - explicit type hints required
    return null;
}

Code quality checks

Option Strict Value Effect
find-unused-expressions true Reports expressions whose results are discarded (e.g., $a + $b;).
find-unused-definitions true Reports unused private methods, variables, and other definitions.
analyze-dead-code true Analyzes and reports on unreachable code paths.
check-missing-override true Reports missing #[Override] attributes on overriding methods (PHP 8.3+).
find-unused-parameters true Reports unused function/method parameters.
no-boolean-literal-comparison true Disallows comparisons like $a === true or $b == false.
enforce-class-finality true Reports classes not declared final, abstract, or annotated with [@api](https://github.com/api).
require-api-or-internal true Requires abstract classes, interfaces, and traits to have [@api](https://github.com/api) or [@internal](https://github.com/internal).
check-experimental true Reports usage of [@experimental](https://github.com/experimental) APIs from non-experimental contexts.
allow-side-effects-in-conditions false Reports impure function calls inside conditions.

Exception handling

Option Strict Value Effect
check-throws true Reports unhandled exceptions not caught or documented with [@throws](https://github.com/throws).

Lenient mode

For a more lenient analysis (useful for legacy codebases or gradual adoption), use:

[analyzer]
# Disable strict checks
check-missing-type-hints = false
strict-list-index-checks = false
no-boolean-literal-comparison = false
enforce-class-finality = false
require-api-or-internal = false

# Enable lenient behaviors
allow-possibly-undefined-array-keys = true
trust-existence-checks = true

# Optionally disable some checks
check-throws = false

:::tip Gradual adoption When introducing Mago to an existing codebase, start with lenient settings and a baseline. Gradually enable stricter options as you improve the codebase. :::

Performance tuning

The analyzer uses internal thresholds to balance analysis depth against performance. These thresholds control how deeply the type inference engine explores complex logical formulas. All settings go under [analyzer.performance] in your mago.toml file.

Option Type Default Description
saturation-complexity-threshold u16 8192 Maximum clauses during CNF saturation.
disjunction-complexity-threshold u16 4096 Maximum clauses per side in OR operations.
negation-complexity-threshold u16 4096 Maximum cumulative complexity when negating formulas.
consensus-limit-threshold u16 256 Upper limit for consensus optimizati...
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport