Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Program Crashing or messages not sending properly on 0.0.10 and 0.1.0 due to History Sync Error #629

@Pachuchi420

Description

@Pachuchi420

TLDR: So the whole caveat has to be some sort of history sync error. Maybe I can do some sort of workaround to ignore any syncing so we can avoid this? I've uploaded a video showcasing the error step by step maybe it'll be helpful for further context!

I've been building a bigger project based on Cobalt and JavaFX to automatically send messages to WhatsApp groups. The functionality works fine in small test groups (e.g., just myself). However, when attempting to send messages in a real WhatsApp group with hundreds or thousands of messages, the behavior breaks down.

Observed behavior:

The UI crashes or hangs when attempting to send.

Sometimes the message appears as the WhatsApp error text: "Please wait until this message loads."

Other times, the message never sends at all.

Expected behavior:
Messages should send reliably in both small and large groups without UI crashes or WhatsApp error messages.

Steps to reproduce:

  1. Create a JavaFX app using Cobalt.
  2. Add a WhatsApp group with heavy activity (hundreds/thousands of messages).
  3. Attempt to send an automated message.

Observe:

UI freeze/hang, or

WhatsApp error "Please wait until this message loads," or

Message not being sent.

Notes:

Works fine in a test group with just me.

Fails consistently in active groups with large message histories.

I've been using the following to initialize the API, I tried using the .historySetting(WhatsappWebHistoryPolicy.discard(false)) to avoid syncing the groups' whole chat history, as I presume that is the issue on what is making the actual real "bigger" group chats on failing with the message sending:

public class Chatbot {
    private static final String PREF_NODE = "com.pach.gsm.chatbot";
    private static final String KEY_SESSION_ID = "session_uuid";
    private static Chatbot instance;



    private static Whatsapp api;



    private boolean loggedIn;


    private boolean wasLoggedIn;
    private boolean turnedOn;



    private boolean enabled;
    private boolean disconnected;


    public static Chatbot getInstance() {
        if (instance == null) {
            instance = new Chatbot();
        }
        return instance;
    }


    public boolean isLoggedIn() {
        return loggedIn;
    }

    public void setLoggedIn(boolean loggedIn) {
        this.loggedIn = loggedIn;
    }


    public boolean isTurnedOn() {
        return turnedOn;
    }

    public void setTurnedOn(boolean turnedOn) {
        this.turnedOn = turnedOn;
    }

    public static Whatsapp getApi() {
        return api;
    }

    public static void setApi(Whatsapp api) {
        Chatbot.api = api;
    }

    public boolean isDisconnected() {
        return disconnected;
    }

    public void setDisconnected(boolean disconnected) {
        this.disconnected = disconnected;
    }


    private UUID loadOrCreateUuid() {
        Preferences prefs = Preferences.userRoot().node(PREF_NODE);
        String raw = prefs.get(KEY_SESSION_ID, "");
        try {
            if (raw == null || raw.isBlank()) {
                UUID fresh = UUID.randomUUID();
                prefs.put(KEY_SESSION_ID, fresh.toString());
                return fresh;
            }
            return UUID.fromString(raw);
        } catch (IllegalArgumentException bad) {
            UUID fresh = UUID.randomUUID();
            prefs.put(KEY_SESSION_ID, fresh.toString());
            return fresh;
        }
    }

    public void initializeChatbot(){

        String baseDir = System.getProperty("user.home") + File.separator + "Documents" + File.separator + "GSM" + File.separator + "qr.png";
        Path qrFile = Path.of(baseDir);
        try {
            Files.createDirectories(qrFile.getParent());
        } catch (Exception e) {
            throw new RuntimeException("Could not prepare QR directory", e);
        }

        api = Whatsapp.builder()
                .webClient()
                .newConnection(loadOrCreateUuid())
                .historySetting(WhatsappWebHistoryPolicy.discard(false))
                .unregistered(
                        WhatsappVerificationHandler.Web.QrCode.toFile(
                                qrFile,
                                savedPath -> {
                                    System.out.println("✅ QR Code saved at: " + savedPath.toAbsolutePath());
                                }
                        )
                )
                .addLoggedInListener(api -> {
                    System.out.println("✅ Whatsapp logged in");
                    setLoggedIn(true);
                    setWasLoggedIn(false);
                    setDisconnected(false);
                })
                .addDisconnectedListener(reason -> {
                    System.out.println("❌ Whatsapp disconnected " +  reason);
                    setDisconnected(true);
                    setLoggedIn(false);
                })
                /*.addListener(new SalesListener())*/
                .connect();

    }

    public void qrImageThread(ImageView qrImageView) {
        Thread checker = new Thread(() -> {
            String baseDir = System.getProperty("user.home") + File.separator + "Documents" + File.separator + "GSM" + File.separator + "qr.png";
            File qrFile = new File(baseDir);

            while (true) {
                if (Authentication.checkIfOnline()) {

                    // If we are disconnected but file exists
                    if (!isLoggedIn() && qrFile.exists()) {
                        Platform.runLater(() -> {
                            qrImageView.setImage(new Image(qrFile.toURI().toString()));
                        });
                    } else if (!isLoggedIn() && wasLoggedIn()){
                        Platform.runLater(() -> {
                            qrImageView.setImage(new Image(qrFile.toURI().toString()));
                        });
                    } else {
                        qrImageView.setImage(null);
                    }
                }
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    System.out.println("❌ QR Image thread interrupted: " + e.getMessage());
                    break;
                }
            }
        });

        checker.setDaemon(true);
        checker.start();
    }



    public void logout(){
        if (isLoggedIn()){
            api.logout();
            api.store().deleteSession();
            System.out.println("✅ WhatsApp session disconnected successfully & session deleted!");
            setLoggedIn(false);
            setWasLoggedIn(true);
            setDisconnected(true);
            Chatbot.getInstance().initializeChatbot();
        } else {
            System.out.println("❌ Not connected, can't log out! ");
        }

    }


    public void sendTestMessage(String groupName){
        var chat = Chatbot.getApi().store()
                .findChatByName(groupName)
                .orElseThrow(() -> new NoSuchElementException("❌ Chat not found!"));
        Chatbot.getApi().sendMessage(chat, "Hello there I'm using Garage Sale Manager 🤓");
    }


    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }


    public List<String> getAllChats() {
        return Chatbot.getApi()
                .store()
                .chats()
                .stream()
                .filter(chat -> chat.name() != null && !chat.name().isBlank()) // has a display name
                .map(Chat::name)
                .distinct()
                .sorted(String.CASE_INSENSITIVE_ORDER)
                .toList();
    }



    public boolean wasLoggedIn() {
        return wasLoggedIn;
    }

    public void setWasLoggedIn(boolean wasLoggedIn) {
        this.wasLoggedIn = wasLoggedIn;
    }



}

When adding the personal group (that is the group where I am the singular member), or scanning the QR Code for login, I get the following error (this didn't use to happen back in earlier versions of cobalt):

Aug. 20, 2025 4:07:31 PM it.auties.whatsapp.api.WhatsappErrorHandler lambda$defaultErrorHandler$3
SCHWERWIEGEND: [4917683241706] Socket failure at HISTORY_SYNC: Ignored failure
java.lang.NullPointerException: title cannot be null
	at java.base/java.util.Objects.requireNonNull(Objects.java:246)
	at it.auties.whatsapp.model.button.base.ButtonSection.<init>(ButtonSection.java:22)
	at it.auties.whatsapp.model.button.base.ButtonSectionSpec.decode(ButtonSectionSpec.java:57)
	at it.auties.whatsapp.model.message.button.ListMessageSpec.decode(ListMessageSpec.java:98)
	at it.auties.whatsapp.model.message.model.MessageContainerSpec.decode(MessageContainerSpec.java:356)
	at it.auties.whatsapp.model.info.ChatMessageInfoSpec.decode(ChatMessageInfoSpec.java:284)
	at it.auties.whatsapp.model.sync.HistorySyncMessageSpec.decode(HistorySyncMessageSpec.java:44)
	at it.auties.whatsapp.model.chat.ChatSpec.decode(ChatSpec.java:209)
	at it.auties.whatsapp.model.sync.HistorySyncSpec.decode(HistorySyncSpec.java:114)
	at it.auties.whatsapp.socket.message.MessageComponent.downloadHistorySyncNotification(MessageComponent.java:1272)
	at java.base/java.util.Optional.map(Optional.java:260)
	at it.auties.whatsapp.socket.message.MessageComponent.downloadHistorySync(MessageComponent.java:1263)
	at it.auties.whatsapp.socket.message.MessageComponent.onHistorySyncNotification(MessageComponent.java:1241)
	at it.auties.whatsapp.socket.message.MessageComponent.handleProtocolMessage(MessageComponent.java:1197)
	at it.auties.whatsapp.socket.message.MessageComponent.saveMessage(MessageComponent.java:1168)
	at it.auties.whatsapp.socket.message.MessageComponent.decodeChatMessage(MessageComponent.java:1046)
	at it.auties.whatsapp.socket.message.MessageComponent.lambda$decode$28(MessageComponent.java:795)
	at java.base/java.lang.Iterable.forEach(Iterable.java:75)
	at it.auties.whatsapp.socket.message.MessageComponent.decode(MessageComponent.java:795)
	at it.auties.whatsapp.socket.SocketConnection.decodeMessage(SocketConnection.java:280)
	at it.auties.whatsapp.socket.stream.MessageHandler.execute(MessageHandler.java:13)
	at it.auties.whatsapp.socket.stream.NodeHandler$Executor.lambda$handle$0(NodeHandler.java:38)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.VirtualThread.run(VirtualThread.java:329)

I'm open to suggestions!

Thanks Again!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions