fix(parser): emit no-root diagnostic when no root component resolves#632
Open
Shinyaigeek wants to merge 1 commit into
Open
fix(parser): emit no-root diagnostic when no root component resolves#632Shinyaigeek wants to merge 1 commit into
no-root diagnostic when no root component resolves#632Shinyaigeek wants to merge 1 commit into
Conversation
A program with statements but no resolvable root component (e.g. only `$state`/literal/data declarations) returned `root: null` with empty `errors`/`unresolved`/`orphaned` — no signal at all that a top-level component statement was missing. `pickEntryId` falls back to the first statement even when none is a component, and `buildResult` then set `root` to null silently when it materialized to a non-element. Add a `no-root` ValidationErrorCode and emit it from `buildResult` when the entry resolves to a non-component value. Gated two ways to avoid noise: - `!wasIncomplete` — root is legitimately null mid-stream. - `errors.length === 0` — don't double-report when something else (e.g. `missing-required` on `root = Stack()`) already explains it. `enrichErrors` adds an actionable hint pointing at the `root = ...` convention, so the automated correction loop can recover. Tests cover: $state-only, literal-entry, and data-only programs emit `no-root`; valid root does not; no double-report with missing-required; no emit mid-stream. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
This is a kind of proposal to provide more information in error message, so please feel free to close this if this is not acceptable 🙏
A program that parses successfully but contains no resolvable root component — e.g. only
$statedeclarations, a top-level literal, or pure data statements — returnedroot: nullwith emptymeta.errors,unresolved, andorphaned. There was no diagnostic at all indicating that a top-level component statement was missing.This was reported by a coding agent integrating against the parser:
Reproduction (before)
rooterrorsunresolvedorphaned$data = ["a", "b"]null[][][]greeting = "hello"null[][][]$items = [1,2,3]/$count = 3null[][][]Root cause
pickEntryIdfalls back to the first statement even when none is a component, andbuildResultthen silently setroot = nullwhen that entry materialized to a non-element — without pushing any error. It's the one null-root path that emitted no diagnostic (unknown-component, missing-required, etc. all push aValidationError).Fix
no-rootcode toValidationErrorCode(so it flows through toOpenUIErrorCode).buildResult, emitno-rootwhen the entry resolves to a non-component value. Gated two ways to avoid noise:!wasIncomplete— root is legitimately null mid-stream.errors.length === 0— don't double-report when something else (e.g.missing-requiredonroot = Stack()) already explains the null root.enrichErrorsattaches an actionable hint pointing at theroot = <Component>(...)convention, so the automated correction loop can recover on its own.Tests
6 new cases under
no-root diagnostic:$state-only / literal-entry / data-only programs emitno-root; a valid root does not; no double-report alongsidemissing-required; and no emit mid-stream while input is incomplete.Full
lang-coresuite: 79/79 pass.tsc --noEmit: clean.Note
Follow-up (not in this PR): the troubleshooting doc's error-code list doesn't yet mention
no-root, and the spec frames a missing root as "nothing renders" (silent). Happy to update the docs in a separate change.🤖 Generated with Claude Code