composer/composer · error · RuntimeException

Invalid value for 'bin-compat

Error message

Invalid value for 'bin-compat': {$value}. Expected auto, full or proxy

What it means

Thrown by Config::get() for 'bin-compat' when the resolved value is not one of auto/full/proxy/symlink. The bin-compat setting controls how Composer installs package binaries (vendor/bin) for cross-platform compatibility. The error message lists auto, full, proxy (symlink is accepted but deprecated since 2.2).

Solutions

  1. Set a valid value: `composer config bin-compat auto` (or 'full' for Windows-compat, 'proxy' for shims).
  2. Check COMPOSER_BIN_COMPAT env var: `echo $COMPOSER_BIN_COMPAT` and unset if stale.
  3. Edit composer.json config.bin-compat to "auto", "full", "proxy" ("symlink" deprecated).
  4. Run `composer validate` to confirm the config parses.

Example fix

// before (composer.json)
"config": { "bin-compat": "compat" }

// after
"config": { "bin-compat": "full" }
Defensive patterns

Strategy: validation

Validate before calling

function isValidBinCompat(string $v): bool {
    return in_array(strtolower($v), ['auto','full','proxy','symlink'], true);
}
$val = getenv('COMPOSER_BIN_COMPAT') ?: ($config['bin-compat'] ?? 'auto');
if (!isValidBinCompat((string) $val)) {
    throw new \InvalidArgumentException("Invalid bin-compat: $val");
}

Type guard

function isValidBinCompat(string $v): bool {
    return in_array(strtolower($v), ['auto','full','proxy','symlink'], true);
}

Prevention

When it happens

Trigger: Setting config.bin-compat in composer.json or COMPOSER_BIN_COMPAT env var to an invalid string. Guard at line 471: `!in_array($value, ['auto','full','proxy','symlink'])`.

Common situations: Typo (e.g. 'compat', 'full2', 'TRUE'), wrong casing ('Auto'), or copy-pasting an outdated value. The COMPOSER_BIN_COMPAT env var silently overrides config so a stray export can also cause it.

Related errors


AI-assisted analysis of composer/composer@c435d285c9 (2026-08-07). Data as JSON: /api/errors/dcec7e539a17aef2. Report an issue: GitHub.

Appendix: source

Thrown at src/Composer/Config.php:472

                return max(0, (int) $size);

            // special cases below
            case 'cache-files-ttl':
                if (isset($this->config[$key])) {
                    return max(0, (int) $this->config[$key]);
                }

                return $this->get('cache-ttl');

            case 'home':
                return rtrim($this->process(Platform::expandPath($this->config[$key]), $flags), '/\\');

            case 'bin-compat':
                $value = $this->getComposerEnv('COMPOSER_BIN_COMPAT') ?: $this->config[$key];

                if (!in_array($value, ['auto', 'full', 'proxy', 'symlink'])) {
                    throw new \RuntimeException(
                        "Invalid value for 'bin-compat': {$value}. Expected auto, full or proxy"
                    );
                }

                if ($value === 'symlink') {
                    trigger_error('config.bin-compat "symlink" is deprecated since Composer 2.2, use auto, full (for Windows compatibility) or proxy instead.', E_USER_DEPRECATED);
                }

                return $value;

            case 'discard-changes':
                $env = $this->getComposerEnv('COMPOSER_DISCARD_CHANGES');
                if ($env !== false) {
                    if (!in_array($env, ['stash', 'true', 'false', '1', '0'], true)) {
                        throw new \RuntimeException(
                            "Invalid value for COMPOSER_DISCARD_CHANGES: {$env}. Expected 1, 0, true, false or stash"
                        );
                    }

View on GitHub (pinned to c435d285c9)