{"record":{"id":"1f63a942d274e491","repo":"composer/composer","slug":"invalid-input","errorCode":null,"errorMessage":"Invalid input","messagePattern":"Invalid input","errorType":"validation","errorClass":"UnexpectedValueException","httpStatus":null,"severity":"warning","filePath":"src/Composer/Command/SelfUpdateCommand.php","lineNumber":344,"sourceCode":"\n        return 0;\n    }\n\n    /**\n     * @throws \\Exception\n     */\n    protected function fetchKeys(IOInterface $io, Config $config): void\n    {\n        if (!$io->isInteractive()) {\n            throw new \\RuntimeException('Public keys can not be fetched in non-interactive mode, please run Composer interactively');\n        }\n\n        $io->write('Open <info>https://composer.github.io/pubkeys.html</info> to find the latest keys');\n\n        $validator = static function ($value): string {\n            $value = (string) $value;\n            if (!Preg::isMatch('{^-----BEGIN PUBLIC KEY-----$}', trim($value))) {\n                throw new \\UnexpectedValueException('Invalid input');\n            }\n\n            return trim($value).\"\\n\";\n        };\n\n        $devKey = '';\n        while (!Preg::isMatch('{(-----BEGIN PUBLIC KEY-----.+?-----END PUBLIC KEY-----)}s', $devKey, $match)) {\n            $devKey = $io->askAndValidate('Enter Dev / Snapshot Public Key (including lines with -----): ', $validator);\n            while ($line = $io->ask('', '')) {\n                $devKey .= trim($line).\"\\n\";\n                if (trim($line) === '-----END PUBLIC KEY-----') {\n                    break;\n                }\n            }\n        }\n        file_put_contents($keyPath = $config->get('home').'/keys.dev.pub', $match[0]);\n        $io->write('Stored key with fingerprint: ' . Keys::fingerprint($keyPath));\n","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/composer/composer/blob/c435d285c9120efdca35696769c72ea9fdcc0466/src/Composer/Command/SelfUpdateCommand.php#L326-L362","documentation":"Thrown by the input validator used while prompting for a public key during --update-keys. The first line pasted must match the PEM header '-----BEGIN PUBLIC KEY-----' exactly (after trim); anything else fails validation. It is an \\UnexpectedValueException, and because it is raised inside the askAndValidate() validator the prompt simply re-asks the user rather than aborting the command.","triggerScenarios":"During `composer self-update --update-keys`, pasting a first line that is not exactly '-----BEGIN PUBLIC KEY-----' — missing dashes, extra whitespace, pasting a fingerprint instead, or a wrong-format key block (SelfUpdateCommand.php:341-345).","commonSituations":"Copying only part of the PEM header; pasting an SSH/PGP key by mistake; trailing spaces from a copy; pasting the key fingerprint rather than the PEM body.","solutions":["Copy the full PEM block from https://composer.github.io/pubkeys.html starting at '-----BEGIN PUBLIC KEY-----' and ending at '-----END PUBLIC KEY-----'.","Paste the BEGIN line verbatim as the first input.","If the validator keeps rejecting, re-copy from the official pubkey page avoiding extra whitespace."],"exampleFix":"// before (first pasted line)\nBEGIN PUBLIC KEY\n// after\n-----BEGIN PUBLIC KEY-----","handlingStrategy":"validation","validationCode":"// Pre-validate the first line before pasting it into the prompt\n$firstLine = trim($input);\nif (!preg_match('{^-----BEGIN PUBLIC KEY-----$}', $firstLine)) {\n    fwrite(STDERR, \"First line must be exactly '-----BEGIN PUBLIC KEY-----'.\\n\");\n}","typeGuard":"function isPemHeader(string $line): bool\\n{\\n    return preg_match('{^-----BEGIN PUBLIC KEY-----$}', trim($line)) === 1;\\n}","tryCatchPattern":null,"preventionTips":["Copy the entire PEM block from the official pubkey page.","Paste the BEGIN header line exactly, including all five dashes on each side.","Don't paste the fingerprint or an SSH key by mistake."],"tags":["cli","self-update","keys","validation","interactive"],"backgroundTag":null,"analyzedSha":"c435d285c9120efdca35696769c72ea9fdcc0466","analyzedAt":"2026-08-07T18:58:23.525Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}