symfony/translation · error · InvalidArgumentException

$batch argument must be one of

Error message

$batch argument must be one of ["%s", "%s", "%s"].

What it means

moveMessagesToIntlDomainsIfPossible() validates the $batch argument against the three class constants ALL_BATCH, NEW_BATCH, OBSOLETE_BATCH inside a match expression. Any other value hits the default arm and throws InvalidArgumentException.

Solutions

  1. Use the constants: AbstractOperation::ALL_BATCH, ::NEW_BATCH, ::OBSOLETE_BATCH
  2. Validate/normalize the $batch input before forwarding it to the operation

Example fix

// before
$operation->moveMessagesToIntlDomainsIfPossible('new');
// after
$operation->moveMessagesToIntlDomainsIfPossible(AbstractOperation::NEW_BATCH);
Defensive patterns

Strategy: validation

Validate before calling

if (!in_array($batch, [AbstractOperation::ALL_BATCH, AbstractOperation::NEW_BATCH, AbstractOperation::OBSOLETE_BATCH], true)) {
    throw new \InvalidArgumentException('Invalid batch');
}

Type guard

function isValidBatch(string $batch): bool {
    return in_array($batch, [AbstractOperation::ALL_BATCH, AbstractOperation::NEW_BATCH, AbstractOperation::OBSOLETE_BATCH], true);
}

Try / catch

try {
    $operation->moveMessagesToIntlDomainsIfPossible($batch);
} catch (\InvalidArgumentException $e) {
    $this->logger->warning('Invalid batch argument', ['batch' => $batch]);
}

Prevention

When it happens

Trigger: Calling $operation->moveMessagesToIntlDomainsIfPossible('new') or 'all' instead of the constants; passing null, an int, or a mistyped string.

Common situations: Wrapping diff()/intersect()/custom operations and forwarding an unvalidated batch parameter; older code written before the constants existed.

Understand the failure class

Background: "invalid argument", "unknown mode", "not supported": invalid enum-like argument errors explained — this error's family across 19 libraries.

Related errors


AI-assisted analysis of symfony/translation@ae9e8a51bc (2026-09-15). Data as JSON: /api/errors/a12bfa2afbdcb14a. Report an issue: GitHub.

Appendix: source

Thrown at Catalogue/AbstractOperation.php:161

    }

    /**
     * @param self::*_BATCH $batch
     */
    public function moveMessagesToIntlDomainsIfPossible(string $batch = self::ALL_BATCH): void
    {
        // If MessageFormatter class does not exist, intl domains are not supported.
        if (!class_exists(\MessageFormatter::class)) {
            return;
        }

        foreach ($this->getDomains() as $domain) {
            $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
            $messages = match ($batch) {
                self::OBSOLETE_BATCH => $this->getObsoleteMessages($domain),
                self::NEW_BATCH => $this->getNewMessages($domain),
                self::ALL_BATCH => $this->getMessages($domain),
                default => throw new \InvalidArgumentException(\sprintf('$batch argument must be one of ["%s", "%s", "%s"].', self::ALL_BATCH, self::NEW_BATCH, self::OBSOLETE_BATCH)),
            };

            if (!$messages || (!$this->source->all($intlDomain) && $this->source->all($domain))) {
                continue;
            }

            $result = $this->getResult();
            $allIntlMessages = $result->all($intlDomain);
            $currentMessages = array_diff_key($messages, $result->all($domain));
            $result->replace($currentMessages, $domain);
            $result->replace($allIntlMessages + $messages, $intlDomain);

            foreach ($result->getCatalogueMetadata('', $domain) ?? [] as $key => $value) {
                if (null === $this->result->getCatalogueMetadata($key, $intlDomain)) {
                    $result->setCatalogueMetadata($key, $value, $intlDomain);
                }
            }
        }

View on GitHub (pinned to ae9e8a51bc)