Skip to content

Bug: No validation rules for the placeholder: "4". #9596

Closed
@kvdpxne

Description

@kvdpxne

PHP Version

8.4

CodeIgniter4 Version

4.6.1

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

Windows

Which server did you use?

apache

Database

No response

What happened?

When validating an array with 5 or more items using a regex_match rule containing curly braces (e.g., \d{4} or \d{6}), CodeIgniter throws a CodeIgniter\Exceptions\LogicException: No validation rules for the placeholder: "4". You must set the validation rules for the field. See <https://codeigniter4.github.io/userguide/libraries/validation.html#validation-placeholders>

My observations:

  • The error only occurs when the data array has ≥5 items (index 4 triggers the bug).
  • The issue stems from CodeIgniter's parser misinterpreting numeric curly braces inside the regex pattern as validation placeholders (e.g., {4}).

I might be misunderstanding how validation placeholders interact with regex patterns. If this is expected behavior, clarification in documentation would be appreciated.

Steps to Reproduce

<?php

namespace placeholders;

use CodeIgniter\Test\CIUnitTestCase;
use Config\Services;

final class RegexTest extends CIUnitTestCase {

  private array $rules = [
    '*.uid' => [
      'label' => 'Order.uid',
      'rules' => [
        'if_exist',
        'required',
        'string',
        'regex_match[/^(\d{4})\/(0[1-9]|1[0-2])\/\d{6}$/]' // Contains {4} and {6}  
      ]
    ]
  ];

  private array $data = [
    ['uid' => '2025/06/000001'],
    ['uid' => '2025/06/000002'],
    ['uid' => '2025/06/000003'],
    ['uid' => '2025/06/000004']
  ];

  public function testLessThat5() {
    $validation = Services::validation();
    $validation->reset();
    $validation->setRules($this->rules);

    // Works with 4 items
    self::assertTrue($validation->run($this->data));
  }

  public function testEqualTo5() {
    $validation = Services::validation();
    $validation->reset();
    $validation->setRules($this->rules);

    // Fails with 5 items (index 4 triggers the bug)
    $largerData = array_merge($this->data, [['uid' => '2025/06/000005']]);

    // Throws CodeIgniter\Exceptions\LogicException
    self::assertTrue($validation->run($largerData));
  }
}

Expected Output

Validation should ignore curly braces inside regex patterns and run successfully regardless of:

  • The presence of {n} in regex patterns.
  • The size of the data array (including arrays with ≥5 items).

Anything else?

Root Cause:
The validation parser incorrectly scans regex patterns (delimited by /.../) for placeholders like {4}. When the data array has 5+ items, the index 4 is misinterpreted as a placeholder requiring validation rules.

Workaround:
As a temporary solution, you can use a custom validation rule to bypass the parser issue:

// Custom rule
public function valid_uid(string $uid): bool {
  return (bool) preg_match('/^(\d{4})\/(0[1-9]|1[0-2])\/\d{6}$/', $uid);
}

// Rules definition  
'rules' => [  
    'required',  
    'valid_uid' // No regex pattern in string -> no parsing issues  
]  

Although the above custom rule allows avoiding this problem, I think that using such a workaround shouldn't be necessary :/

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugVerified issues on the current code behavior or pull requests that will fix them

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions