composer/composer · error · InvalidArgumentException
Script "%s" is not defined in this package
Error message
Script "%s" is not defined in this package
What it means
Thrown when the requested script has no registered listeners — i.e. it is not defined under `scripts` in composer.json (and no plugin handles it). hasEventListeners() returns false, so dispatch would be a no-op and Composer rejects it instead. It is an \InvalidArgumentException.
Source
Thrown at src/Composer/Command/RunScriptCommand.php:125
}
$script = $input->getArgument('script');
if ($script === null) {
throw new \RuntimeException('Missing required argument "script"');
}
if (!in_array($script, $this->scriptEvents)) {
if (defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
throw new \InvalidArgumentException(sprintf('Script "%s" cannot be run with this command', $script));
}
}
$composer = $this->requireComposer();
$devMode = $input->getOption('dev') || !$input->getOption('no-dev');
$event = new ScriptEvent($script, $composer, $this->getIO(), $devMode);
$hasListeners = $composer->getEventDispatcher()->hasEventListeners($event);
if (!$hasListeners) {
throw new \InvalidArgumentException(sprintf('Script "%s" is not defined in this package', $script));
}
$args = $input->getArgument('args');
if (null !== $timeout = $input->getOption('timeout')) {
if (!ctype_digit($timeout)) {
throw new \RuntimeException('Timeout value must be numeric and positive if defined, or 0 for forever');
}
// Override global timeout set before in Composer by environment or config
ProcessExecutor::setTimeout((int) $timeout);
}
Platform::putEnv('COMPOSER_DEV_MODE', $devMode ? '1' : '0');
return $composer->getEventDispatcher()->dispatchScript($script, $devMode, $args);
}
protected function listScripts(OutputInterface $output): intView on GitHub (pinned to c435d285c9)
Solutions
- List defined scripts with `composer run-script --list` and use an exact name.
- Add the script to composer.json under `scripts` if it should exist.
- Confirm you are in the project root that owns the composer.json defining the script.
- Watch for case and hyphen vs underscore mismatches in the name.
Example fix
// before composer run-script tesst // after (after `composer run-script --list`) composer run-script test
Defensive patterns
Strategy: validation
Validate before calling
$data = json_decode((string) file_get_contents(getcwd() . '/composer.json'), true);
$scripts = array_keys($data['scripts'] ?? []);
if (!in_array($name, $scripts, true)) {
fwrite(STDERR, "Script '$name' is not defined. Defined: " . implode(', ', $scripts) . "\n");
exit(1);
} Type guard
function scriptIsDefined(string $composerJson, string $name): bool\n{\n $data = json_decode((string) file_get_contents($composerJson), true);\n return is_array($data) && isset($data['scripts'][$name]);\n} Try / catch
try {\n // run `composer run-script <name>`\n} catch (\InvalidArgumentException $e) {\n if (str_contains($e->getMessage(), 'is not defined in this package')) {\n // list scripts, fix the name, retry\n }\n} Prevention
- Run `composer run-script --list` to copy exact script names.
- Confirm you're in the project root that owns the composer.json defining the script.
- Standardize script naming (lowercase, hyphen-separated) to avoid mismatches.
When it happens
Trigger: Running `composer run-script <name>` where <name> is neither a custom script in composer.json `scripts` nor an event with plugin listeners (RunScriptCommand.php:123-125).
Common situations: Typo in script name; running in the wrong project (no composer.json or different one); script was removed/renamed; copy-paste from a tutorial whose script keys differ.
Related errors
- Missing required argument "script"
- Script "%s" cannot be run with this command
- Timeout value must be numeric and positive if defined, or 0
- "scripts-aliases" element array values should contain only s
- There is no ${name} repository defined
AI-assisted analysis of composer/composer@c435d285c9 (2026-08-07).
Data as JSON: /api/errors/3434f1b68bd3bea8.
Report an issue: GitHub.