composer/composer · error · InvalidArgumentException
Unknown action "{action}". Use add-source.
Error message
Unknown action "{action}". Use add-source. What it means
Thrown by `composer policy` (PolicyCommand.php:122, the `default` switch arm) when the required `action` argument is anything other than `add-source`. The command currently supports only one sub-action; any other value (including typos or plausible-but-unimplemented actions like `remove`, `list`, `enable`) lands in the default arm and is rejected with an `InvalidArgumentException`.
Source
Thrown at src/Composer/Command/PolicyCommand.php:122
foreach ($currentSources as $existing) {
if (is_array($existing)
&& ($existing['type'] ?? null) === $sourceConfig['type']
&& ($existing['url'] ?? null) === ($sourceConfig['url'] ?? null)
) {
$this->getIO()->write('<info>Source '.$sourceConfig['url'].' already present in policy '.$listName.'</info>');
return 0;
}
}
$currentSources[] = $sourceConfig;
$this->configSource->addConfigSetting('policy.'.$listName.'.sources', $currentSources);
return 0;
default:
throw new \InvalidArgumentException('Unknown action "'.$action.'". Use add-source.');
}
}
private function assertCustomListName(string $name): void
{
if (in_array($name, PolicyConfig::BUILTIN_LIST_NAMES, true)) {
throw new \RuntimeException('Built-in dependency policy "'.$name.'" does not support sources. Use `composer config policy.'.$name.'.<field>` to configure it.');
}
$error = PolicyConfig::getFutureReservedListNameError($name);
if ($error !== null) {
throw new \RuntimeException($error);
}
if ($name === '' || strpos($name, '.') !== false) {
throw new \RuntimeException('Invalid dependency policy name "'.$name.'".');
}
}View on GitHub (pinned to 6ffc117740)
Solutions
- Use the only supported action: `composer policy add-source <name> <type> <url>`.
- Check the exact spelling — it is `add-source` with a hyphen, not `addsource` or `add_source`.
- Run `composer policy --help` to list the accepted action value for your Composer build.
Example fix
// before composer policy remove my-policy // after composer policy add-source my-policy url https://example.org/pkgs.json
Defensive patterns
Strategy: validation
Validate before calling
$allowedActions = ['add-source'];
if (!in_array(strtolower($action), $allowedActions, true)) {
fwrite(STDERR, 'Unknown action. Supported: ' . implode(', ', $allowedActions) . PHP_EOL);
exit(2);
} Type guard
function isSupportedPolicyAction(string $action): bool {
return in_array(strtolower($action), ['add-source'], true);
} Prevention
- Pin the action spelling to `add-source` (hyphenated) in scripts.
- Run `composer policy --help` after upgrading Composer to check supported actions.
When it happens
Trigger: Running `composer policy remove my-policy`, `composer policy list`, `composer policy show`, or any misspelling such as `composer policy addsource` or `composer policy add_source`. The `action` argument is `REQUIRED` so it cannot be omitted, but it is not constrained to a value-set at the input layer — only validated inside `execute()`.
Common situations: Assuming the policy command mirrors the repo command's sub-actions (list/add/remove); typoing `add-source`; using an older/newer Composer version whose supported actions differ; scripting against an action that was renamed.
Related errors
- Source JSON must be an object.
- You must pass the source type and a url. Example: composer p
- Built-in dependency policy "{name}" does not support sources
- Invalid dependency policy name "{name}".
- Not enough arguments (missing: "packages").
AI-assisted analysis of composer/composer@6ffc117740 (2026-08-07).
Data as JSON: /api/errors/fc284b87f2181ace.
Report an issue: GitHub.