{"record":{"id":"6ce840d2d7925dd5","repo":"phalcon/cphalcon","slug":"role-rolename-to-inherit-produces-an-infinit","errorCode":null,"errorMessage":"Role '{roleName}' (to inherit) produces an infinite loop","messagePattern":"Role '(.+?)' \\(to inherit\\) produces an infinite loop","errorType":"exception","errorClass":"Phalcon\\Acl\\Exceptions\\CircularInheritanceError","httpStatus":null,"severity":"warning","filePath":"phalcon/Acl/Adapter/Memory.zep","lineNumber":368,"sourceCode":"                 * Walk the inheritance queue with an integer cursor instead\n                 * of `array_shift`. New roles enqueued by the body land at\n                 * the end of `checkRoleToInherits`, so advancing `pendingIndex`\n                 * preserves FIFO order without paying `array_shift`'s O(n)\n                 * reindex per pop.\n                 */\n                let pendingIndex = 0;\n                while pendingIndex < count(checkRoleToInherits) {\n                    let checkRoleToInherit = checkRoleToInherits[pendingIndex];\n                    let pendingIndex++;\n\n                    if isset usedRoleToInherits[checkRoleToInherit] {\n                        continue;\n                    }\n\n                    let usedRoleToInherits[checkRoleToInherit] = true;\n\n                    if unlikely roleName == checkRoleToInherit {\n                        throw new CircularInheritanceError(roleInheritName);\n                    }\n\n                    /**\n                     * Push inherited roles\n                     */\n                    if isset this->roleInherits[checkRoleToInherit] {\n                        for usedRoleToInherit in this->roleInherits[checkRoleToInherit] {\n                            array_push(checkRoleToInherits, usedRoleToInherit);\n                        }\n                    }\n                }\n            }\n\n            let this->roleInherits[roleName][] = roleInheritName;\n        }\n\n        return true;\n    }","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Acl/Adapter/Memory.zep#L350-L386","documentation":"Queue producers extend Phalcon\\Queue\\Adapter\\AbstractProducer, whose default setDeliveryDelay() treats any non-null argument as unsupported and throws DeliveryDelayNotSupportedException. A null value (the default) is accepted and is a no-op; only requesting an actual delay triggers the throw. Transports that do support delayed delivery override this method.","triggerScenarios":"$producer->setDeliveryDelay(5000) (or any non-null value) on a producer whose transport inherits the base implementation, e.g. the Beanstalk or Redis queue adapters in this codebase.","commonSituations":"Writing transport-agnostic code against ProducerInterface that calls all feature setters; porting code from a broker supporting delays (RabbitMQ, SQS) to beanstalk-style transports; feature flags turning delay on globally.","solutions":["Do not call setDeliveryDelay() on transports without delay support, or call it with null explicitly.","Check whether your concrete producer class overrides setDeliveryDelay() before relying on the feature.","If delayed delivery is a hard requirement, switch to a transport that implements it (e.g. an AMQP-based backend)."],"exampleFix":"// before\n$producer->setDeliveryDelay(5000); // throws on transports without delay support\n\n// after\n// only set a delay when the transport advertises support\nif (get_class($producer) !== \\Phalcon\\Queue\\Adapter\\AbstractProducer::class\n    && method_exists($producer, 'setDeliveryDelay')) {\n    // still guard: the base implementation throws for non-null values\n}\n// safest: simply omit the call on unsupported transports\n$producer->send($queue, $message);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $producer->setDeliveryDelay(5000);\n} catch (\\Phalcon\\Queue\\Exceptions\\DeliveryDelayNotSupportedException $e) {\n    // transport cannot delay: enqueue now, or choose another transport\n    $logger->warning('Delay unsupported by this transport; sending immediately');\n}","preventionTips":["Check the concrete producer class: only transports overriding setDeliveryDelay() accept non-null values.","Keep broker-specific feature calls behind an interface guarded by capability detection."],"tags":["queue","producer","delivery-delay","unsupported-feature"],"backgroundTag":"queue-feature-not-supported","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}