{"record":{"id":"0a3c32819399ba75","repo":"phalcon/cphalcon","slug":"prefix-must-be-a-string","errorCode":null,"errorMessage":"'prefix' must be a string","messagePattern":"'prefix' must be a string","errorType":"exception","errorClass":"Phalcon\\Mvc\\View\\Engine\\Volt\\Exceptions\\InvalidOptionType","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/View/Engine/Volt/Compiler.zep","lineNumber":355,"sourceCode":"                );\n            } else {\n                let compileAlways = false;\n            }\n        }\n\n        if unlikely typeof compileAlways != \"boolean\" {\n            throw new InvalidOptionType(\"always\", \"bool value\");\n        }\n\n        /**\n         * Prefix is prepended to the template name\n         */\n        if !fetch prefix, options[\"prefix\"] {\n            let prefix = \"\";\n        }\n\n        if unlikely typeof prefix != \"string\" {\n            throw new InvalidOptionType(\"prefix\", \"string\");\n        }\n\n        /**\n         * Compiled path is a directory where the compiled templates will be\n         * located\n         */\n        if !fetch compiledPath, options[\"path\"] {\n            if fetch compiledPath, options[\"compiledPath\"] {\n                trigger_error(\n                    \"The 'compiledPath' option is deprecated. Use 'path' instead.\",\n                    E_USER_DEPRECATED\n                );\n            } else {\n                let compiledPath = \"\";\n            }\n        }\n\n        /**","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/View/Engine/Volt/Compiler.zep#L337-L373","documentation":"The Volt 'prefix' option — a string prepended to compiled template names, used to avoid collisions between compiled files of different apps sharing one cache dir — must be a string; any other type throws InvalidOptionType('prefix', 'string') at phalcon/Mvc/View/Engine/Volt/Compiler.zep:355. It defaults to '' when omitted.","triggerScenarios":"setOptions(['prefix' => 0]) or null from a missing config key; a numeric prefix (e.g. tenant ID) passed uncast: ['prefix' => $tenant->id]; array passed by accident.","commonSituations":"Multi-tenant setups keying compiled templates by tenant with an int ID; INI/JSON config parsing numbers as ints/floats; copying options arrays between projects with changed shapes.","solutions":["Cast to string: 'prefix' => (string) $tenantId","Omit the key entirely when no prefix is needed (default '')","Validate the whole options array shape once in your Volt factory"],"exampleFix":"// before\n$volt->setOptions(['prefix' => $tenant->id]); // int\n\n// after\n$volt->setOptions(['prefix' => (string) $tenant->id]);","handlingStrategy":"validation","validationCode":"if (isset($options['prefix']) && !is_string($options['prefix'])) {\n    $options['prefix'] = (string) $options['prefix'];\n}","typeGuard":"function isVoltPrefixValid(mixed $prefix): bool\n{\n    return !isset($prefix) || is_string($prefix);\n}","tryCatchPattern":null,"preventionTips":["Cast numeric/nullable prefixes to string","Omit 'prefix' when unused","Validate the whole Volt options array in one factory method"],"tags":["phalcon","volt","compiler","options","type-validation"],"backgroundTag":"config-type-mismatch","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}