Repository: zauberzeug/nicegui

Issue #3410: Large websocket messages cause error that is silently caught somewhere
Created: 2024-07-28T10:56:57Z
Description
Description
When ui.textarea contains more than a million characters, it starts to behave unpredictably without any visible warnings.
Steps to Reproduce
To demonstrate the issue from different perspectives, I wrote the following code:
from nicegui import ui

@ui.page('/')
def main():
    text_area = ui.textarea('Type something').props('rounded outlined input-class=mx-3') \
                .classes('w-full self-center')

    text_area.value = '123' + 'A'*1_000_000

    len_label = ui.label('Length').classes('mt-2')
    
    def text_area_length():
        print('Length:', len(text_area.value))
        len_label.set_text(f'Length: {len(text_area.value)}')
        print('first_character:', text_area.value[0])

    def text_area_delete_first():
        text_area.value = text_area.value[1:]
        text_area_length()

    ui.button('Calculate', on_click=text_area_length)
    ui.button('Delete first character', on_click=text_area_delete_first)

    text_area_length()

ui.run(title='Text Input Max')
When you run this code, it creates a textarea filled with over a million characters, plus three more to make the behavior more evident in different scenarios.

If you click the Calculate button immediately after launching (without interacting with the ui.textarea), everything is calculated correctly, and the console prints the appropriate values.
If you add or delete a character using the ui.textarea (e.g., delete the digit 1 at the beginning or add a new character), the Calculate button will no longer calculate the new value of text_area correctly. The code executes without errors, and you see the print output, but it shows the wrong number of characters and the first character is also incorrect, as if the connection between the frontend and backend is lost.
To further investigate, I created a button to delete the first character without using the cursor to interact with the ui.textarea. In this case, everything works as expected, the counter decreases, and the first characters are read correctly.

Additional Investigation
To see if this is a Quasar issue, I added character counting to their textarea code:
https://codepen.io/Xtreemrus/pen/XWLNPyY?editors=101
<!--
Forked from:
https://quasar.dev/vue-components/input#example--textarea
-->
<div id="q-app" style="min-height: 100vh;">
  <div class="q-pa-md" style="max-width: 300px">
    <q-input
      v-model="text"
      filled
      type="textarea"
    ></q-input>
    <div class="q-mt-md">
      <p>Calculate len: {{ characterCount }}</p>
      <p>first_character: {{ firstCharacter }}</p>
    </div>
  </div>
</div>
JS part:
const { ref, computed } = Vue

const app = Vue.createApp({
  setup () {
    const text = ref('')

    const characterCount = computed(() => text.value.length)
    
    const firstCharacter = computed(() => {
      if (text.value.length > 0) {
        return text.value[0]
      } else {
        return 'No symbols'
      }
    })

    return {
      text,
      characterCount,
      firstCharacter
    }
  }
})

app.use(Quasar, { config: {} })
app.mount('#q-app')
In this case, working with a million characters is handled correctly.
Impact
A couple of years ago, cases requiring a million characters in a textarea were rare. However, with the development of LLMs, users are inserting increasingly large chunks of information into input fields. One million characters are approximately 250,000 tokens, which is now a feasible amount.
Difficulty
The challenge with this bug is that no visible errors occur, neither on the user side nor the developer side. There are no exceptions thrown, making it hard to find a workaround.
Environment

Browser: Chrome
NiceGUI version: 1.4.30

Duplicate issue #4546: NiceGUI Vue Component does not call callback with large parameters
Created: 2025-03-29T02:04:36Z
First Check

 I added a very descriptive title here.
 This is not a Q&A. I am sure something is wrong with NiceGUI or its documentation.
 I used the GitHub search to find a similar issue and came up empty.

Description
My environment

Windows11
Python v3.12.7
nicegui v2.13.0

Problem Summary
When using $emit in Vue component to trigger a Python callback, events are not emitted if the size of the parameters being passed is large.
While smaller parameters work correctly, when over about 1MB , the event does not trigger, and the Python callback is not invoked.
The test code is shown below.
Test Code Explanation:
The test uses the q-file component to select a file, encodes it in Base64, and passes this text to the Python callback.
When the Base64 encoded text exceeds around 1MB, the event stops triggering, and the Python callback is no longer called.
test.py
from nicegui import ui
from nicegui.element import Element

class TestComponent(Element, component="test.vue"):
    def __init__(self):
        super().__init__()
        self.on("change_file", self._on_change_file)

    def _on_change_file(self, event):
        log.push(f"{event.args['name']} : {event.args['data']}")

ui.label("Event test")
TestComponent()
log = ui.log()

ui.run()
test.vue
<template>
    <q-file outlined v-model="model" @update:model-value="value => onFileChange(value)" />
</template>

<script>
export default {
    props: {
    },
    data() {
        return {
            model: null,
        }
    },
    mounted() {
    },
    methods: {
        onFileChange(e) {
            e.arrayBuffer().then((buffer) => {
                // encode to base64
                const base64 = btoa(
                    new Uint8Array(buffer)
                        .reduce((data, byte) => data + String.fromCharCode(byte), '')
                );
                console.log(base64);
                this.$emit('change_file', {
                    name: e.name,
                    data: base64
                });
            });
        },
    },
}
</script>
NiceGUI Version
2.13.0
Python Version
3.12.7
Browser
Chrome
Operating System
Windows
Additional Context
No response

Closing comment (2025-03-29T04:19:28Z): This is a duplicate of #3410.