{"record":{"id":"e2f105e3b3ac88e7","repo":"symfony/translation","slug":"the-writer-class-s-does-not-implement-the-getformats-method","errorCode":null,"errorMessage":"The writer class \"%s\" does not implement the \"getFormats()\" method.","messagePattern":"The writer class \"(.+?)\" does not implement the \"getFormats\\(\\)\" method\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"Command/TranslationExtractCommand.php","lineNumber":71,"sourceCode":"     * @param \\Closure():KernelInterface|KernelInterface $kernel\n     */\n    public function __construct(\n        private \\Closure|KernelInterface $kernel,\n        private TranslationWriterInterface $writer,\n        private TranslationReaderInterface $reader,\n        private ExtractorInterface $extractor,\n        private string $defaultLocale,\n        private ?string $defaultTransPath = null,\n        private ?string $defaultViewsPath = null,\n        private array $transPaths = [],\n        private array $codePaths = [],\n        private array $enabledLocales = [],\n    ) {\n        $this->enabledLocales = array_filter($enabledLocales);\n        parent::__construct();\n\n        if (!method_exists($writer, 'getFormats')) {\n            throw new \\InvalidArgumentException(\\sprintf('The writer class \"%s\" does not implement the \"getFormats()\" method.', $writer::class));\n        }\n    }\n\n    protected function configure(): void\n    {\n        $this\n            ->setDefinition([\n                new InputArgument('locale', InputArgument::REQUIRED, 'The locale'),\n                new InputArgument('bundle', InputArgument::OPTIONAL, 'The bundle name or directory where to load the messages'),\n                new InputOption('prefix', null, InputOption::VALUE_REQUIRED, 'Override the default prefix', '__'),\n                new InputOption('no-fill', null, InputOption::VALUE_NONE, 'Extract translation keys without filling in values'),\n                new InputOption('format', null, InputOption::VALUE_REQUIRED, 'Override the default output format', 'xlf12'),\n                new InputOption('dump-messages', null, InputOption::VALUE_NONE, 'Should the messages be dumped in the console'),\n                new InputOption('force', null, InputOption::VALUE_NONE, 'Should the extract be done'),\n                new InputOption('clean', null, InputOption::VALUE_NONE, 'Should clean not found messages'),\n                new InputOption('domain', null, InputOption::VALUE_REQUIRED, 'Specify the domain to extract'),\n                new InputOption('sort', null, InputOption::VALUE_REQUIRED, 'Return list of messages sorted alphabetically'),\n                new InputOption('as-tree', null, InputOption::VALUE_REQUIRED, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'),","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/symfony/translation/blob/ae9e8a51bc29780d63c7f9efd6005d7c875e100b/Command/TranslationExtractCommand.php#L53-L89","documentation":"TranslationExtractCommand requires the injected writer object to expose getFormats() so it can list supported formats for command options. The constructor checks method_exists($writer, 'getFormats') and throws InvalidArgumentException if the check fails.","triggerScenarios":"Constructing TranslationExtractCommand with an object (e.g. a custom TranslationWriterInterface implementation or a mock) that lacks a public getFormats() method; passing the wrong variable to the constructor.","commonSituations":"Custom writer implementations missing the method; wiring errors in Symfony DI where the wrong service is injected; outdated custom writers after upgrading symfony/translation.","solutions":["Add a public static getFormats(): array method to your custom writer class","Inject the correct TranslationWriter service instead of another object","Update the custom writer to match the expected interface"],"exampleFix":"// before\nclass MyWriter { public function write(MessageCatalogue $c, string $f, array $o = []): void {} }\n// after\nclass MyWriter {\n    public function write(MessageCatalogue $c, string $f, array $o = []): void {}\n    public static function getFormats(): array { return ['custom']; }\n}","handlingStrategy":"type-guard","validationCode":"if (!method_exists($writer, 'getFormats')) {\n    throw new \\InvalidArgumentException('Writer must implement getFormats()');\n}","typeGuard":"function isCompatibleWriter(object $writer): bool {\n    return method_exists($writer, 'getFormats');\n}","tryCatchPattern":"try {\n    $command = new TranslationExtractCommand($writer, $loader, $enabledLocales);\n} catch (\\InvalidArgumentException $e) {\n    // inspect injected writer class\n    throw new \\LogicException('Invalid writer injected: '.get_debug_type($writer));\n}","preventionTips":["Make custom writers implement a common interface including getFormats()","Add a static analysis test asserting writer compatibility","Check DI service wiring when constructing the command"],"tags":["php","symfony-console","invalid-constructor-argument"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"ae9e8a51bc29780d63c7f9efd6005d7c875e100b","analyzedAt":"2026-09-15T22:29:15.305Z","contentChangedAt":"2026-09-15T22:29:15.305Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}