I wrote a dataset downloader for e621.net: const axios = require('axios');
const fs = require('fs');
const path = require('path');
const readline = require('readline');
const ProgressBar = require('progress');

/**
 * Prompts the user for input.
 * @param {string} question - The question to display to the user.
 * @returns {Promise<string>} - The user's input.
 */
function getUserInput(question) {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    return new Promise(resolve => {
        rl.question(question, (input) => {
            rl.close();
            resolve(input.trim());
        });
    });
}

/**
 * Retrieves the total number of posts matching the tags.
 * @param {string} tags - The tags to search for.
 * @param {string} username - e621 username.
 * @param {string} apiKey - e621 API key.
 * @returns {Promise<number>} - Total number of posts.
 */
async function getPostCount(tags, username, apiKey) {
    try {
        const response = await axios.get('https://e621.net/posts.json', {
            params: {
                tags: tags,
                limit: 1 // Set limit to 1 to get minimal data
            },
            auth: {
                username: username,
                password: apiKey
            },
            headers: {
                'User-Agent': `e621Downloader/1.0 (by ${username} on e621)`
            }
        });

        const totalPosts = parseInt(response.headers['x-total']);

        if (isNaN(totalPosts)) {
            throw new Error('Unable to retrieve total post count from response headers.');
        }

        return totalPosts;
    } catch (error) {
        console.error('Error fetching post count:', error.response ? error.response.data : error.message);
        return null;
    }
}

/**
 * Downloads the specified number of posts with the given tags.
 * @param {string} tags - Tags for searching posts.
 * @param {number} limit - Number of posts to download.
 * @param {string} destination - Destination folder path.
 * @param {string} username - e621 username.
 * @param {string} apiKey - e621 API key.
 * @param {boolean} describeEnabled - Whether to enable the describe function.
 * @param {boolean} replaceUnderscores - Whether to replace underscores with spaces in tags.
 */
async function downloadPosts(tags, limit, destination, username, apiKey, describeEnabled, replaceUnderscores) {
    let page = 1;
    let downloaded = 0;

    // Initialize progress bar
    const bar = new ProgressBar('Downloading [:bar] :percent (:current/:total)', {
        total: limit,
        width: 40,
        clear: true,
    });

    while (downloaded < limit) {
        const remaining = limit - downloaded;
        const batchSize = remaining > 320 ? 320 : remaining; // e621 limit per request

        try {
            const response = await axios.get('https://e621.net/posts.json', {
                params: {
                    tags: tags,
                    limit: batchSize,
                    page: page
                },
                auth: {
                    username: username,
                    password: apiKey
                },
                headers: {
                    'User-Agent': `e621Downloader/1.0 (by ${username} on e621)`
                }
            });

            const posts = response.data.posts;

            if (posts.length === 0) {
                console.log('No more posts found.');
                break;
            }

            for (let post of posts) {
                if (downloaded >= limit) {
                    break;
                }

                const fileUrl = post.file.url;
                if (!fileUrl) {
                    // Skip if file URL is not available
                    bar.tick();
                    continue;
                }

                const filename = path.basename(fileUrl);
                const filePath = path.join(destination, filename);

                // Check if file already exists
                if (fs.existsSync(filePath)) {
                    // Uncomment the next line if you want to log skipped files
                    // console.log(`${filename} already exists, skipping.`);
                    downloaded++;
                    bar.tick();
                    continue;
                }

                // Download the file
                try {
                    const fileResponse = await axios.get(fileUrl, {
                        responseType: 'stream',
                        headers: {
                            'User-Agent': `e621Downloader/1.0 (by ${username} on e621)`
                        }
                    });

                    const writer = fs.createWriteStream(filePath);
                    fileResponse.data.pipe(writer);

                    await new Promise((resolve, reject) => {
                        writer.on('finish', resolve);
                        writer.on('error', reject);
                    });

                    // If describeEnabled is true, create a .txt file with tags
                    if (describeEnabled) {
                        let allTags = [];
                        for (let category in post.tags) {
                            if (category !== 'meta') {
                                allTags = allTags.concat(post.tags[category]);
                            }
                        }

                        if (replaceUnderscores) {
                            allTags = allTags.map(tag => tag.replace(/_/g, ' '));
                        }

                        const tagsString = allTags.join(', ');

                        const descFilename = path.basename(filename, path.extname(filename)) + '.txt';
                        const descFilePath = path.join(destination, descFilename);

                        fs.writeFileSync(descFilePath, tagsString);
                    }

                    // Uncomment the next line if you want to log each downloaded file
                    // console.log(`Downloaded ${filename}`);
                } catch (error) {
                    console.error(`Failed to download ${fileUrl}`, error.message);
                }

                downloaded++;
                bar.tick();
            }

            page++;
        } catch (error) {
            console.error('Error fetching posts:', error.response ? error.response.data : error.message);
            break;
        }
    }
}

/**
 * Main function to run the script.
 */
async function main() {
    try {
        // Prompt user for e621 credentials and download preferences
        const username = await getUserInput('Enter your e621 username: ');
        const apiKey = await getUserInput('Enter your e621 API key: ');
        const tags = await getUserInput('Enter tags (space-separated): ');
        const destination = await getUserInput('Enter download destination folder: ');

        // Create folder named after the tags
        const tagsFolderName = tags.replace(/\s+/g, '_');
        const downloadFolder = path.join(destination, tagsFolderName);

        if (!fs.existsSync(downloadFolder)) {
            fs.mkdirSync(downloadFolder, { recursive: true });
            console.log(`Created folder: ${downloadFolder}`);
        } else {
            console.log(`Folder already exists: ${downloadFolder}`);
        }

        // Get total amount of media with tags
        const totalPosts = await getPostCount(tags, username, apiKey);

        if (totalPosts === null) {
            console.error('Failed to get total posts count.');
            return;
        }

        console.log(`Total posts found: ${totalPosts}`);

        // Ask user for the number of posts to download
        let amountInput = await getUserInput('Enter the amount you want to download (or "all"): ');

        let amount;
        if (amountInput.toLowerCase() === 'all') {
            amount = totalPosts;
        } else {
            amount = parseInt(amountInput);
            if (isNaN(amount) || amount <= 0) {
                console.error('Invalid amount entered.');
                return;
            }
            if (amount > totalPosts) {
                amount = totalPosts;
                console.log(`Only ${totalPosts} posts available. Adjusted download amount to ${amount}.`);
            }
        }

        // Ask user if they want to enable the describe function
        let describeInput = await getUserInput('Do you want to enable the describe function? (yes/no): ');
        let describeEnabled = (describeInput.toLowerCase() === 'yes' || describeInput.toLowerCase() === 'y');

        let replaceUnderscores = false;
        if (describeEnabled) {
            // Ask if user wants to replace underscores with spaces in tags
            let replaceInput = await getUserInput('Do you want to replace underscores (_) with spaces in tags? (yes/no): ');
            replaceUnderscores = (replaceInput.toLowerCase() === 'yes' || replaceInput.toLowerCase() === 'y');
        }

        // Start downloading
        console.log(`Starting download of ${amount} posts...`);
        await downloadPosts(tags, amount, downloadFolder, username, apiKey, describeEnabled, replaceUnderscores);
        console.log('\nDownload completed.');
    } catch (error) {
        console.error('An error occurred:', error.message);
    }
}

main();
But it shows ans error: Error fetching post count: Unable to retrieve total post count from response headers.
Failed to get total posts count.
How do I fix it?