I don't know what happend after add messages saver

Save chat etc

'use server';

import { generateId } from 'ai';
import { existsSync, mkdirSync } from 'fs';
import { writeFile, readFile } from 'fs/promises';
import path from 'path';
import { Message } from 'ai';

export async function createChat(): Promise<string> {
    try {
        const id = generateId(); // generate a unique chat ID
        const chatFilePath = getChatFile(id);
        await writeFile(chatFilePath, '[]'); // create an empty chat file
        return id;
    } catch (error) {
        throw new Error('Failed to create chat');
    }
}

function getChatFile(id: string): string {
    const chatDir = path.join(process.cwd(), '.chats');
    if (!existsSync(chatDir)) {
        mkdirSync(chatDir, { recursive: true });
    }
    return path.join(chatDir, `${id}.json`);
}

export async function loadChat(id: string): Promise<Message[]> {
    try {
        const chatFilePath = getChatFile(id);
        const data = await readFile(chatFilePath, 'utf8');
        const messages = JSON.parse(data);
        return messages;
    } catch (error) {
        throw new Error('Failed to load chat');
    }
}

export async function saveChat({
    id,
    messages,
}: {
    id: string;
    messages: Message[];
}): Promise<void> {
    try {
        const content = JSON.stringify(messages, null, 2);
        const chatFilePath = getChatFile(id);
        await writeFile(chatFilePath, content);
    } catch (error) {
        throw new Error('Failed to save chat');
    }
}

The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.

{
  "name": "egpyt-gpt-chat",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "browser": {
    "fs": false,
    "path": false,
    "fs/promises": false,
    "os": false
  },
  "dependencies": {
    "@ai-sdk/deepseek": "^0.1.8",
    "@ai-sdk/fal": "^0.0.2",
    "@ai-sdk/fireworks": "^0.1.8",
    "@ai-sdk/google": "^1.1.8",
    "@ai-sdk/groq": "^1.1.7",
    "@ai-sdk/openai": "^1.1.9",
    "@codemirror/highlight": "^0.19.8",
    "@codemirror/lang-python": "^6.1.7",
    "@codemirror/theme-one-dark": "^6.1.2",
    "@fal-ai/client": "^1.2.3",
    "@heroui/react": "^2.6.14",
    "@iconify/react": "^5.2.0",
    "@mdx-js/loader": "^3.1.0",
    "@mdx-js/react": "^3.1.0",
    "@nanostores/react": "github:ai/react",
    "@next/env": "^15.1.6",
    "@next/mdx": "^15.1.6",
    "@prose-ui/core": "^1.0.4",
    "@prose-ui/next": "^1.0.4",
    "@radix-ui/react-avatar": "^1.1.2",
    "@radix-ui/react-collapsible": "^1.1.2",
    "@radix-ui/react-dialog": "^1.1.5",
    "@radix-ui/react-dropdown-menu": "^2.1.5",
    "@radix-ui/react-separator": "^1.1.1",
    "@radix-ui/react-slot": "^1.1.1",
    "@radix-ui/react-switch": "^1.1.2",
    "@radix-ui/react-tooltip": "^1.1.7",
    "@react-aria/ssr": "^3.9.7",
    "@tabler/icons-react": "^3.29.0",
    "@tiptap/core": "^2.11.5",
    "@tiptap/react": "^2.11.5",
    "@tiptap/starter-kit": "^2.11.5",
    "@types/mdx": "^2.0.13",
    "@types/react-syntax-highlighter": "^15.5.13",
    "ai": "^4.1.16",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "codemirror": "^6.0.1",
    "date-fns": "^4.1.0",
    "framer-motion": "^11.18.2",
    "fs": "^0.0.1-security",
    "geist": "^1.3.1",
    "highlight.js": "^11.11.1",
    "js-cookie": "^3.0.5",
    "lucide-react": "^0.474.0",
    "marked": "^15.0.7",
    "next": "14.2.16",
    "next-auth": "^4.24.11",
    "next-themes": "^0.4.4",
    "react": "^18",
    "react-copy-to-clipboard": "^5.1.0",
    "react-dom": "^18",
    "react-markdown": "^9.0.3",
    "react-remarkable": "^1.1.3",
    "react-resizable": "^3.0.5",
    "react-syntax-highlighter": "^15.6.1",
    "rehype-highlight": "^7.0.2",
    "remark-gfm": "^4.0.0",
    "remarkable-react": "^1.4.3",
    "remeda": "^2.20.0",
    "shiki": "^2.3.2",
    "sonner": "^1.7.4",
    "tailwind-merge": "^3.0.1",
    "tailwindcss-animate": "^1.0.7",
    "tiptap-markdown": "^0.3.4",
    "usehooks-ts": "^3.1.1"
  },
  "devDependencies": {
    "@iconify-json/solar": "^1.2.2",
    "@types/js-cookie": "^3.0.6",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-copy-to-clipboard": "^5.0.7",
    "@types/react-dom": "^18",
    "@types/react-resizable": "^3.0.8",
    "@types/remarkable": "^2.0.8",
    "eslint": "^8",
    "eslint-config-next": "14.2.16",
    "postcss": "^8",
    "tailwindcss": "^3.4.1",
    "typescript": "^5"
  }
}

Hi @3frotodev, thanks for posting in the community.

I’m not sure if I understand the issue correctly. Can you add more information about what was the intended behavior and what happened? What is the stack you are using? Where did the issue occur: Vercel or locally?

I’d recommend reading the following post and adding more information to your topic so the community members can help.

Hey Anshuman, sorry for give a Incomplete information about the problem I am facing. I really do not understand the problem well enough to say complete information, but this only happens when I host my site on Vercel I don’t understand exactly why, I followed the Docs and Worked very well but on production happened to me

The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.

Hi @3frotodev, it seems like you’re trying to use filesystem to create folder and write files. It is not supported in a serverless environment. Hence, I’ll suggest you to use serverless storage options such as Vercel Blob to store the chats in a file.

Alternatively, you can also use databases to store the chats.

Oka thanks !, I’ll use database and tell

1 Like

Thanks! It’s working now

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.