Skip to content

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

@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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions