Status report and troubleshooting¶
The status report¶
The status report, at Reports > Status report, has a BlockNote documents entry saying how many stored documents do not render in full, and why. A document renders nothing when its text format is missing, disabled or not a BlockNote format, when it was written for a version of the document format this release does not read, which happens after a downgrade, when it is not a well-formed document, or when it is larger than the limits the site sets (see Troubleshooting). It renders without some of its blocks when it holds a block no installed module provides, one its format does not permit, or markup that could not be converted when its field was converted from formatted text, which has a line of its own (see Converting existing content). A document whose check raised an error, such as a block plugin that throws while it is looked up, is counted too, on a line of its own that says it could not be checked, so whether it renders in full is not known, and to report the error to the module it names, or to the BlockNote issue queue. The first error of each kind in a check, a kind being the exception's class and the line that threw it, is logged on the blocknote channel, and the check goes on from the next document. Each case is one line, naming how many documents, the fields they are in as entity_type.field_name, and what to do. Nothing is rewritten: the stored document is unchanged, and correcting the cause brings its content back.
Cron does the checking, in batches, and the entry says what it has checked and when. Every revision and every translation of a document is checked, and each translation counts as a document of its own. The warning and the lines under it count what the site shows and what it is about to publish: each translation's current revision, and the draft waiting to replace it, such as one in content moderation. So correcting a document and saving it clears its line. A document that does not render in full only in older revisions is counted apart, in one sentence, since only a revision page or a revert shows it, and that count clears only when those revisions are deleted. A cron run spends five seconds on the check, plus the time one revision takes, since it finishes the revision it is reading. It reads as many revisions at a time as $settings['entity_update_batch_size'] in settings.php allows, 50 unless set, fewer when they hold more than 1,000 values or 8 MiB between them, and counts a value larger than the size limit from its length without loading it. A new check starts a day after the last one started, and at once when a BlockNote format, the installed blocks, the document limits or the way documents are checked change. The entry shows the last finished check, or the running one when none has finished yet or the running one has already found something.
drush blocknote:scan-documents checks every document at once and lists each one that does not render in full, in every revision, by field, entity, revision, whether the revision is current, language and delta, with the reasons and the block types, and the error for a document whose check raised one. The status report then shows its result. Cron and the command never check at the same time: cron skips its turn while the command runs, and the command waits up to 30 seconds for a cron run to finish, and otherwise stops with a message.
Three things are not checked. A field of an entity type that does not keep its data in SQL tables is named on the entry as not checked. Inline content that renders as its text without its element is not counted. And the check covers the text format, the document version, the block structure, the size limits and the block types, but not the content inside each block, so a block whose content was stored in a shape the page cannot render, which only code that skips validation can store, renders without that content and is not counted. ADR 0035 records why the check works this way.
Troubleshooting¶
The field offers no text format, or the widget is disabled. Either no BlockNote format exists, or the author has no format they may use, or the field's Allowed text formats names formats none of which the author may use. Check step 2. An author who may not use the stored format gets no editor: core disables the field and puts its own notice in place of the document, This field has been disabled because you do not have sufficient permissions to edit it. That is core's behaviour for a format the user may not use, and the stored document is preserved unchanged on save.
A save is refused, naming block types. The document holds blocks the chosen format does not enable, usually after a format switch or after an administrator turned a block off. The editor keeps those blocks as they were, in a read-only carrier block with a notice, and lists them above the editor. Nothing is dropped and the stored value is never rewritten. Remove them, or switch back to a format that permits them, and save again.
A save is refused, naming blocks no module provides. A module that registered a block was uninstalled while a document still held one, as Media describes for BlockNote Media. Restore the module, or remove the block and save again.
A save is refused, naming a limit. Documents have size limits, which exist so that a single field cannot take a site down: 1,048,576 bytes of stored JSON, 5,000 blocks and 10 levels of nesting. No table size limit ships: a table is one block and its cells are its content, so the byte limit already bounds a table. A site that wants a cap on cells in one table, columns in one table, or table cells across a document sets max_table_cells, max_table_columns or max_document_table_cells to a number. Every one of these is a container parameter, not configuration, so a site that needs different numbers overrides blocknote.limits in sites/default/services.yml:
parameters:
blocknote.limits:
max_bytes: 4194304
max_blocks: 20000
max_depth: 10
max_table_cells: ~ # a number switches the cap on
max_table_columns: ~ # a number switches the cap on
max_document_table_cells: ~ # a number switches the cap on
A key left out keeps its default, and a table key left out or set to ~ sets no limit. One set of numbers serves the editor, the save and the page, so a raised limit is what all three go by, and every save and every page build of a larger document costs more. Raise them with a reason.
A public page renders nothing where the field is. The item's text format is not a BlockNote format, which happens when a format was deleted, or when a document was written programmatically with the wrong format. The module refuses to render rather than fall through to the raw JSON, and logs to the blocknote channel: Refused to render %entity_type %id, field %field, delta @delta: the text format %format is not a BlockNote format. Look for it at /admin/reports/dblog, and for the count of such documents on the status report. Correcting the format invalidates the refusal, so the page fills in without a cache rebuild.
The browser console warns that the viewport meta tag is missing interactive-widget=resizes-content. BlockNote logs this once on every page that shows an editor, unless the page's viewport meta tag carries that value. On a touch device with the on-screen keyboard open, BlockNote draws the formatting toolbar in a bar fixed to the bottom of the visible part of the page rather than beside the selection, and the value asks a browser that reads it to resize the page itself, not only the visible part, when the keyboard opens. The tag belongs to the theme, so the module leaves it alone: Drupal core prints width=device-width, initial-scale=1.0 on every page, and a site that wants the value changes the html_head entry keyed viewport in a hook_page_attachments_alter() implementation. On a desktop browser the warning is the only difference. On a touch device the value reaches beyond the editor: it applies to the whole page, so every page carrying the tag is resized, its layout included, whenever the on-screen keyboard opens, editor or not. The warning is meant for development: BlockNote skips it only where a process global exists, which a browser does not define, so the editor's production bundle logs it too.