composer/composer · error · RuntimeException

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

Error message

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

What it means

Thrown by Config::get() (RuntimeException) for 'bin-compat' when the effective value (from COMPOSER_BIN_COMPAT env or config) is not one of the allowed set. The code at src/Composer/Config.php:471 actually accepts ['auto','full','proxy','symlink'] (symlink triggers a deprecation), but the error message text only mentions 'auto, full or proxy' — a known mismatch between message and accepted set. Any other string triggers the exception.

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 6ffc117740)

Solutions

  1. Use one of the accepted values: 'auto' (default, symlinks on *nix), 'full' (compat copies for Windows), or 'proxy' (proxy wrappers).
  2. 'symlink' is also accepted but deprecated since Composer 2.2 — migrate to 'auto'.
  3. Unset COMPOSER_BIN_COMPAT / remove the config key to fall back to the default 'auto'.

Example fix

// before
$ COMPOSER_BIN_COMPAT=windows composer install
// throws: Invalid value for 'bin-compat': windows. Expected auto, full or proxy

// after: use a supported value (or unset to default to auto)
$ COMPOSER_BIN_COMPAT=full composer install
// or in composer.json: {"config": {"bin-compat": "full"}}
Defensive patterns

Strategy: validation

Validate before calling

// Validate bin-compat before setting it
$allowed = ['auto', 'full', 'proxy', 'symlink'];
if (!in_array($value, $allowed, true)) {
    throw new \InvalidArgumentException("bin-compat '$value' invalid; use one of: auto, full, proxy.");
}

Type guard

/** @param mixed $v */
function isValidBinCompat($v): bool {
    return in_array($v, ['auto', 'full', 'proxy', 'symlink'], true);
}

Try / catch

try {
    $config->get('bin-compat');
} catch (\RuntimeException $e) {
    if (str_contains($e->getMessage(), "Invalid value for 'bin-compat'")) {
        // reset to default and warn (note: 'symlink' is accepted but deprecated)
        $config->merge(['config' => ['bin-compat' => 'auto']]);
        return 'auto';
    }
    throw $e;
}

Prevention

When it happens

Trigger: Setting COMPOSER_BIN_COMPAT or config.bin-compat to an unrecognized value like 'windows', 'both', 'true', or an empty string.

Common situations: Confusing bin-compat with a boolean; using a value from outdated docs or a different tool; typo in 'proxy'/'full'; message itself misleading users who set 'symlink' (which works but is deprecated).

Related errors


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