coollabsio/coolify · error · RuntimeException
Unable to write the CSV file.
Error message
Unable to write the CSV file.
What it means
RuntimeException thrown by the private writeCsvRow() helper inside the cloud:export-users Artisan command when PHP's fputcsv() returns false. fputcsv only fails when the underlying stream cannot be written to: the handle is invalid or closed, the file was opened in a non-writable mode, the disk backing the 'backups' storage disk is full, or permissions were revoked mid-run. The command opens both CSV targets with fopen($path, 'wb') on the backups disk before the loop, so a successful open followed by a failed write points at runtime I/O failure (usually disk space), not a bad path.
Source
Thrown at app/Console/Commands/Cloud/ExportUsers.php:124
} finally {
fclose($subscribedOutput);
fclose($unsubscribedOutput);
}
$this->info("Exported {$subscribedCount} subscribed verified users to {$subscribedPath}");
$this->info("Exported {$unsubscribedCount} unsubscribed verified users to {$unsubscribedPath}");
return self::SUCCESS;
}
/**
* @param resource $output
* @param array<int, mixed> $fields
*/
private function writeCsvRow($output, array $fields): void
{
if (fputcsv($output, $fields, ',', '"', '') === false) {
throw new RuntimeException('Unable to write the CSV file.');
}
}
}
View on GitHub (pinned to 70b9acc424)
Solutions
- Check free space and write permission on the directory behind Storage::disk('backups') (df -h and touch on the backups path); free space if full.
- Verify the backups disk entry in config/filesystems.php points at a reachable, writable location and remount/fix the mount if stale, then re-run php artisan cloud:export-users.
- Confirm the CLI user has write access to cloud-users-subscribed.csv / cloud-users-unsubscribed.csv in that directory.
- If the disk is remote, fix its credentials/mount health before re-running; the command deletes and recreates the files each run so it is safe to retry.
Defensive patterns
Strategy: try-catch
Validate before calling
$dir = dirname(Storage::disk('backups')->path('cloud-users-subscribed.csv'));
if (! is_writable($dir) || disk_free_space($dir) < 1024 * 1024) {
// abort before opening any stream: the volume is unwritable or nearly full
} Try / catch
try {
$this->writeCsvRow($output, $fields);
} catch (RuntimeException $e) {
$this->error("CSV write failed mid-export: {$e->getMessage()}");
return self::FAILURE;
} Prevention
- Monitor free space on the backups volume and alert before it fills
- Run the export as the same user that owns the backups directory
- Smoke-test exports with a bounded query (limit) before running the full table
When it happens
Trigger: Running php artisan cloud:export-users on Coolify Cloud while (a) the filesystem behind the backups disk runs out of space as User rows stream in via lazyById(500), (b) the backups disk points at a full or unreachable remote mount (NFS/S3-compatible) that fails after fopen succeeded, or (c) the handle is closed/invalidated mid-export. Every writeCsvRow() call (header row plus one row per verified user) checks fputcsv's return and throws on the first false.
Common situations: Disk-full on the volume configured for the backups disk in config/filesystems.php; stale NFS mounts or expired S3-compatible credentials on the mount; large user tables where an external log-rotation or cleanup process touches the target files mid-export; running the command as a user whose permissions were changed after fopen.
AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17).
Data as JSON: /api/errors/105c67a0b6760c5c.
Report an issue: GitHub.