Problem
A published post created/updated through the CLI can render normally and remain valid in Substack's primary rich-text editor, yet make the browser edit screen unstable or crash.
Verified reproduction: https://rareinsights.substack.com/p/death-by-donation-a-repugnant-transaction (post ID 210551946). The public page is healthy, but the authenticated published-post editor logs:
Editor content error encountered: Error: [tiptap error]: Invalid JSON content
RangeError: Unknown node type: image
Differential diagnosis
Confirmed
The published-post edit screen mounts two visible Tiptap editors:
- The primary editor accepts the complete stored post JSON without an error.
- A secondary restricted editor exposes only
doc, paragraph, text, and hardBreak, with basic link/bold/italic marks, but receives the full rich body.
The secondary editor rejects rich nodes present in the post:
image (first observed failure)
heading
blockquote
orderedList / bulletList via listItem
It also renders a second, very long document tree beside the primary editor. In the reproduction, the primary document was approximately 15,434 px tall and the secondary copy approximately 11,170 px tall. The schema exception plus duplicated DOM is the leading explanation for browser-tab instability.
Ruled out for this post
- corrupted or malformed ProseMirror JSON
- invalid content in Substack's full editor schema
- excessive individual string/node size
- duplicate node IDs
- broken image URLs or failed asset requests
- repository-relative reader links
- public-page HTTP, console, or page errors
The body is about 51.5 KB / 536 JSON objects and all three images load.
Related but distinct compatibility defect
A scheduled control post containing a table fails in the primary editor with:
RangeError: Unknown node type: tableHeader
This is a genuine CLI/editor schema-compatibility problem and should not be conflated with the published-post secondary-editor defect.
Remaining uncertainty
The secondary editor's intended Substack function is not established. This may be a Substack regression, an undocumented published-revision representation constraint, or a post shape that triggers an otherwise latent editor bug. The CLI should therefore diagnose and contain the failure without claiming ownership of Substack's UI internals.
Detection options
A. Static capability profiles (recommended baseline)
Validate generated nodes and marks against versioned profiles:
- full draft editor profile
- restricted auxiliary editor profile
- published-revision profile
Report the first incompatible node with its JSON path and all incompatible-node counts.
Trade-off: deterministic and fast, but profiles can drift when Substack changes its private editor schema.
B. Authenticated disposable-editor canary
Create or update a non-public canary, open the authenticated edit route, capture Tiptap errors, mounted editor schemas, DOM duplication, and page stability, then delete/restore the canary.
Trade-off: detects upstream drift but is slower, authentication-dependent, potentially rate-limited, and must never perform unconfirmed publication.
C. Stored-post round-trip inspection
After create/update, retrieve the post and compare draft_body, published body, metadata, and node inventory; classify published-revision risk before reporting success.
Trade-off: catches transport differences but cannot alone prove the browser editor will mount safely.
D. Payload complexity guardrails
Record body bytes, node count/depth, image/list/table counts, and estimated duplicated DOM cost.
Trade-off: useful diagnostics, not a substitute for schema validation; thresholds risk false positives.
Resolution options
1. Fail closed on known incompatible nodes for editable published revisions
Reject or require explicit override when a target profile cannot represent the body.
Benefit: safest and transparent.
Cost: blocks otherwise publishable rich posts when only Substack's auxiliary editor is defective.
2. Normalize only unsupported structures
Examples: convert tables to accessible Markdown/HTML-safe lists; preserve headings/images for the full editor; produce a paragraph-safe auxiliary representation only if the API has a distinct supported field.
Benefit: retains most formatting.
Cost: lossy and unsafe unless the secondary representation is an actual supported API concept.
3. Editor-native round trip
Serialize through the exact schema discovered from the authenticated primary editor, then verify the resulting published-revision screen.
Benefit: strongest compatibility signal.
Cost: coupled to private implementation details and still may not control the secondary editor.
4. CLI-only update fallback
When the browser editor is known unsafe, permit update-in-place through the CLI and emit a durable warning/receipt.
Benefit: immediate operational continuity.
Cost: workaround only; users remain unable to use Substack's browser editor.
5. Upstream escalation with minimal reproducer
Provide Substack a privacy-safe fixture containing one heading, image, blockquote, and list that the full editor accepts but the secondary editor rejects.
Benefit: targets the actual UI defect.
Cost: external resolution and timing are outside this project's control.
Recommendation
Implement layered protection:
- Add static full/restricted/published-revision schema profiles and precise JSON-path diagnostics.
- Treat tables unsupported by the primary editor as a hard error unless explicitly normalized.
- Treat secondary-editor incompatibility as a prominent published-editability risk, not silent success.
- Add an authenticated disposable canary to the compatibility matrix, with rate-limit, CAPTCHA/2FA, cleanup, and no-publication boundaries.
- Preserve CLI update-in-place as a documented contingency.
- Produce a minimal upstream reproduction and avoid destructive rewriting until Substack's secondary editor contract is understood.
Acceptance criteria
Scope boundary
Planning and diagnostics must not silently modify published content, strip rich structures, or claim Substack UI compatibility without an authenticated verification receipt.
Problem
A published post created/updated through the CLI can render normally and remain valid in Substack's primary rich-text editor, yet make the browser edit screen unstable or crash.
Verified reproduction:
https://rareinsights.substack.com/p/death-by-donation-a-repugnant-transaction(post ID210551946). The public page is healthy, but the authenticated published-post editor logs:Differential diagnosis
Confirmed
The published-post edit screen mounts two visible Tiptap editors:
doc,paragraph,text, andhardBreak, with basic link/bold/italic marks, but receives the full rich body.The secondary editor rejects rich nodes present in the post:
image(first observed failure)headingblockquoteorderedList/bulletListvialistItemIt also renders a second, very long document tree beside the primary editor. In the reproduction, the primary document was approximately 15,434 px tall and the secondary copy approximately 11,170 px tall. The schema exception plus duplicated DOM is the leading explanation for browser-tab instability.
Ruled out for this post
The body is about 51.5 KB / 536 JSON objects and all three images load.
Related but distinct compatibility defect
A scheduled control post containing a table fails in the primary editor with:
This is a genuine CLI/editor schema-compatibility problem and should not be conflated with the published-post secondary-editor defect.
Remaining uncertainty
The secondary editor's intended Substack function is not established. This may be a Substack regression, an undocumented published-revision representation constraint, or a post shape that triggers an otherwise latent editor bug. The CLI should therefore diagnose and contain the failure without claiming ownership of Substack's UI internals.
Detection options
A. Static capability profiles (recommended baseline)
Validate generated nodes and marks against versioned profiles:
Report the first incompatible node with its JSON path and all incompatible-node counts.
Trade-off: deterministic and fast, but profiles can drift when Substack changes its private editor schema.
B. Authenticated disposable-editor canary
Create or update a non-public canary, open the authenticated edit route, capture Tiptap errors, mounted editor schemas, DOM duplication, and page stability, then delete/restore the canary.
Trade-off: detects upstream drift but is slower, authentication-dependent, potentially rate-limited, and must never perform unconfirmed publication.
C. Stored-post round-trip inspection
After create/update, retrieve the post and compare
draft_body, publishedbody, metadata, and node inventory; classify published-revision risk before reporting success.Trade-off: catches transport differences but cannot alone prove the browser editor will mount safely.
D. Payload complexity guardrails
Record body bytes, node count/depth, image/list/table counts, and estimated duplicated DOM cost.
Trade-off: useful diagnostics, not a substitute for schema validation; thresholds risk false positives.
Resolution options
1. Fail closed on known incompatible nodes for editable published revisions
Reject or require explicit override when a target profile cannot represent the body.
Benefit: safest and transparent.
Cost: blocks otherwise publishable rich posts when only Substack's auxiliary editor is defective.
2. Normalize only unsupported structures
Examples: convert tables to accessible Markdown/HTML-safe lists; preserve headings/images for the full editor; produce a paragraph-safe auxiliary representation only if the API has a distinct supported field.
Benefit: retains most formatting.
Cost: lossy and unsafe unless the secondary representation is an actual supported API concept.
3. Editor-native round trip
Serialize through the exact schema discovered from the authenticated primary editor, then verify the resulting published-revision screen.
Benefit: strongest compatibility signal.
Cost: coupled to private implementation details and still may not control the secondary editor.
4. CLI-only update fallback
When the browser editor is known unsafe, permit update-in-place through the CLI and emit a durable warning/receipt.
Benefit: immediate operational continuity.
Cost: workaround only; users remain unable to use Substack's browser editor.
5. Upstream escalation with minimal reproducer
Provide Substack a privacy-safe fixture containing one heading, image, blockquote, and list that the full editor accepts but the secondary editor rejects.
Benefit: targets the actual UI defect.
Cost: external resolution and timing are outside this project's control.
Recommendation
Implement layered protection:
Acceptance criteria
tableHeaderincompatibility before any live write.Scope boundary
Planning and diagnostics must not silently modify published content, strip rich structures, or claim Substack UI compatibility without an authenticated verification receipt.