phalcon/cphalcon · error · Phalcon\Translate\Exceptions\FileOpenError
Error opening translation file '{file}'
Error message
Error opening translation file '{file}' What it means
Csv::load() opens the file from options['content'] via fopen($file, 'rb'); when fopen() fails (returns false instead of a resource) the adapter throws Phalcon\Translate\Exceptions\FileOpenError with the path in the message (phalcon/Translate/Adapter/Csv.zep:140). This happens during construction, before any translation is requested.
Source
Thrown at phalcon/Translate/Adapter/Csv.zep:140
* and skipped.
*
* @phpstan-param int<0, max> $length
*
* @throws FileOpenError
*/
private function load(
string file,
int length,
string delimiter,
string enclosure,
string escape
) -> void {
var data, fileHandler;
let fileHandler = this->phpFopen(file, "rb");
if unlikely typeof fileHandler !== "resource" {
throw new FileOpenError(file);
}
loop {
let data = this->phpFgetCsv(fileHandler, length, delimiter, enclosure, escape);
if data === false {
break;
}
if substr(data[0], 0, 1) === "#" || !isset data[1] {
continue;
}
let this->translate[data[0]] = data[1];
}
this->phpFclose(fileHandler);
}View on GitHub (pinned to b7419de9cd)
Solutions
- Use an absolute path built from a known anchor: dirname(__DIR__) . '/messages/en.csv' or a config value.
- Check is_readable($path) before instantiating and fail with a clear application error.
- Verify the file is deployed and readable by the web/CLI user; check open_basedir when on restricted hosting.
Example fix
// before $t = new Csv($factory, ['content' => 'messages/en.csv']); // relative, CWD-dependent // after $t = new Csv($factory, ['content' => dirname(__DIR__) . '/messages/en.csv']);
Defensive patterns
Strategy: validation
Validate before calling
$file = $options['content'] ?? '';
if (!is_string($file) || !is_readable($file)) {
throw new RuntimeException("Translation file not readable: {$file}");
}
$t = new Csv($factory, $options); Try / catch
use Phalcon\Translate\Exceptions\FileOpenError;
try {
$t = new Csv($factory, $options);
} catch (FileOpenError $e) {
$logger->error($e->getMessage());
$t = new NativeArray($factory, ['content' => []]); // empty fallback dictionary
} Prevention
- Always use absolute paths derived from a known anchor (dirname(__DIR__), project root config).
- Include locale CSV files in the deploy artifact and verify permissions for the web/CLI user.
- Check open_basedir restrictions on shared hosting before pointing at locale directories.
When it happens
Trigger: Constructing Csv with a nonexistent or misspelled path, a file the PHP process cannot read (permissions), a path blocked by open_basedir, or a relative path resolved from an unexpected CWD (CLI worker vs web).
Common situations: Relative paths that work under FPM but break in CLI/cron/workers; deployment pipelines that skip the locale CSV files; case-sensitivity differences between dev (macOS/Windows) and prod Linux; shared-hosting open_basedir restrictions.
Related errors
- Parameter 'content' is required
- Cannot find translation key: {key}
- Translate is an immutable ArrayAccess object
- This class requires the gettext extension for PHP
- Parameter 'locale' is required
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/d4fd37c156f22ae8.
Report an issue: GitHub.