fix(vega-lite): render vconcat charts with faceted/repeated children#14065
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This stack of pull requests is managed by Graphite. Learn more about stacking. |
✅ PR preview is ready!
|
There was a problem hiding this comment.
Pull request overview
Fixes a Vega-Lite rendering regression in Streamlit where vconcat charts containing facet or repeat children could fail with “infinite extent” errors when using width="stretch", by expanding nested-composition detection so these charts use safer autosizing behavior.
Changes:
- Extend nested composition detection to include
facetandrepeatin both Python and TypeScript. - Add backend + frontend unit tests covering
facet/repeatdetection and sizing behavior. - Add an E2E regression scenario for issue #14050 and assert the chart renders visible graphics.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| lib/streamlit/elements/vega_charts.py | Backend nested-composition detection updated to include facet/repeat for autosize decisions. |
| lib/tests/streamlit/elements/vega_charts_test.py | Adds backend tests for nested composition detection and autosize behavior with faceted children. |
| frontend/lib/src/components/elements/ArrowVegaLiteChart/useVegaElementPreprocessor.ts | Frontend preprocessing skips forcing child widths for facet/repeat vconcat children to avoid “infinite extent”. |
| frontend/lib/src/components/elements/ArrowVegaLiteChart/useVegaElementPreprocessor.test.ts | Adds unit tests ensuring widths are skipped for facet/repeat children. |
| frontend/lib/src/components/elements/ArrowVegaLiteChart/ArrowVegaLiteChart.tsx | Updates nested-composition detection to treat facet/repeat as nested compositions. |
| frontend/lib/src/components/elements/ArrowVegaLiteChart/ArrowVegaLiteChart.test.tsx | Adds unit tests for facet/repeat nested composition detection. |
| e2e_playwright/st_altair_chart.py / e2e_playwright/st_altair_chart_test.py | Adds and validates an E2E regression chart for issue #14050 rendering. |
Comments suppressed due to low confidence (2)
frontend/lib/src/components/elements/ArrowVegaLiteChart/useVegaElementPreprocessor.ts:175
generateSpecassumesspec.vconcatis an array and callsspec.vconcat.forEach(...)after only checking"vconcat" in spec. If a malformed spec setsvconcatto a non-array value, this will throw at runtime in the preprocessor. Consider guarding withArray.isArray(spec.vconcat)(or similar) before iterating.
if (useContainerWidth && containerWidth && containerWidth > 0) {
spec.width = containerWidth
if ("vconcat" in spec) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- TODO: Replace 'any' with a more specific type.
spec.vconcat.forEach((child: any) => {
// Skip non-object children (defensive check)
if (child === null || typeof child !== "object") {
return
}
// Skip setting width on children that are nested compositions
// (hconcat, vconcat, concat, facet, repeat) as it causes
// "infinite extent" errors.
// Layer children should still receive width so layered + vconcat charts
// can stretch consistently.
// In valid Vega-Lite specs, composition operators are always top-level keys.
if (
"hconcat" in child ||
"vconcat" in child ||
"concat" in child ||
"facet" in child ||
"repeat" in child
) {
return
}
child.width = containerWidth
})
}
lib/streamlit/elements/vega_charts.py:293
- The
_has_nested_compositiondocstring still states that only(hconcat, vconcat, concat, layer)are top-level composition keys, but the function now treatsfacetandrepeatas compositions too. Please update that sentence/list so the documentation matches the actual detection logic.
In valid Vega-Lite specs, composition operators (hconcat, vconcat, concat, layer)
are always top-level keys of a view specification. They cannot be buried inside
encoding, mark, or other nested properties. This allows us to check only the
immediate children of vconcat for nested composition operators.
frontend/lib/src/components/elements/ArrowVegaLiteChart/ArrowVegaLiteChart.tsx
Outdated
Show resolved
Hide resolved
Consolidated Code ReviewSummaryThis PR fixes a rendering regression where Vega-Lite charts using The fix adds
This now correctly covers all six Vega-Lite multi-view composition operators. Code QualityThe changes are minimal, well-targeted, and consistent across all three code locations. The fix follows existing patterns perfectly. Both reviewers agreed on high code quality with no blocking issues. Minor issues (both reviewers agreed):
Both are documentation-only nits and don't affect correctness. Test CoverageBoth reviewers rated test coverage as strong. Tests span all three layers:
One gap (both reviewers agreed): The Python backend tests add a Backwards CompatibilityNo backwards compatibility concerns. Both reviewers agreed. The change only broadens detection of composition operators that already triggered the Security & RiskNo security concerns. Both reviewers agreed. The changes are purely in rendering logic for chart specifications. Regression risk is low because:
AccessibilityNo accessibility impact. Both reviewers agreed. The changes affect Vega-Lite chart rendering logic (autosize and width configuration) and do not modify DOM structure, ARIA attributes, or keyboard interactions. Reviewer AgreementBoth reviewers (
Recommendations
All three are minor and non-blocking. VerdictAPPROVED: Clean, well-tested bugfix that correctly extends the Vega-Lite composition operator detection to include Consolidated review by 📋 Review by `gpt-5.3-codex-high`SummaryThis PR fixes Vega-Lite rendering regressions for Code QualityThe implementation is focused and consistent across layers, with clear intent and good alignment between frontend ( No blocking code quality issues found. Non-blocking observation:
Test CoverageCoverage is strong overall for the regression path:
Residual gap (non-blocking):
Backwards CompatibilityNo breaking API changes were introduced. Security & RiskNo security concerns identified. AccessibilityNo new interactive UI patterns or semantic markup changes were introduced in frontend rendering components. Recommendations
VerdictAPPROVED: The fix is well-scoped, coherent across frontend/backend, and adequately tested for the reported regression scenario. This is an automated AI review by 📋 Review by `opus-4.6-thinking`SummaryThis PR fixes a regression where Vega-Lite charts using The fix adds
This now covers all six Vega-Lite multi-view composition operators. Code QualityThe changes are minimal, well-targeted, and consistent across all three code locations. The fix follows the existing patterns perfectly. Minor issues:
Both are documentation-only nits and don't affect correctness. Test CoverageTest coverage is thorough and well-structured:
One gap:
Backwards CompatibilityNo backwards compatibility concerns. The change only broadens the detection of composition operators that already triggered the "pad" autosize fallback path. Charts that previously worked (simple vconcat, vconcat+layer, etc.) are unaffected. Charts that previously failed to render (vconcat+facet, vconcat+repeat) will now render correctly. Security & RiskNo security concerns. The changes are purely in rendering logic for chart specifications. The risk of regression is low because:
AccessibilityNo accessibility impact. The changes affect Vega-Lite chart rendering logic (autosize and width configuration) and do not modify DOM structure, ARIA attributes, or keyboard interactions. Recommendations
All three are minor and non-blocking. VerdictAPPROVED: Clean, well-tested bugfix that correctly extends the Vega-Lite composition operator detection to include This is an automated AI review by |
Treat `facet` and `repeat` children under `vconcat` as nested compositions in both backend autosize selection and frontend width preprocessing. This prevents forced stretch sizing that can trigger Vega "Infinite extent" errors and blank chart renders (issue #14050). Add regression coverage across Python unit tests, frontend unit tests, and E2E altair chart tests.
fcbc0d3 to
bd1892e
Compare

Describe your changes
Fixed a regression where Vega-Lite charts with
vconcatcontaining faceted or repeated children would fail to render with "infinite extent" errors when usingwidth="stretch". The issue occurred because the width preprocessing logic only checked for composition operators (hconcat,vconcat,concat,layer) but not for multi-view compositions (facet,repeat).Updated the nested composition detection logic in both frontend and backend to include
facetandrepeatoperators, ensuring these chart types usepadautosize instead offit-xto prevent rendering errors.GitHub Issue Link (if applicable)
Fixes #14050
Testing Plan
facetandrepeatdetection in both frontend (ArrowVegaLiteChart.test.tsx,useVegaElementPreprocessor.test.ts) and backend (vega_charts_test.py)test_vconcat_layered_facet_regression_rendersthat verifies the chart renders correctly and contains visible graphics elementsContribution License Agreement
By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.