Nested tblr breaks vertical alignment
In the following, both columns should be header-aligned
\documentclass[paper=b5]{scrartcl}
\usepackage{tabularray}
\newsavebox\SomeNumbers
\sbox\SomeNumbers{\begin{tblr}{hlines, vlines}1 & 2 & 3\end{tblr}}
\begin{document}
\begin{tblr}{colspec={X[l, h]X[l, h]} , hlines, vlines}
{Fill \\ some \\ boxes} & \begin{tblr}{hlines, vlines}1 & 2 & 3\end{tblr} \\
{Fill \\ some \\ more \\ boxes} & \usebox\SomeNumbers
\end{tblr}
\end{document}
but they aren't

Footer-alignment suffers from the same problem. As a workaround, saving nested tblr is a box restores the proper alignment, as the example shows, but nonetheless.
I can confirm this is a bug. In this case, you could use t alignment as another workaround.
\begin{tblr}{colspec={X[l, t]X[l, t]} , hlines, vlines}
{Fill \\ some \\ boxes} & \begin{tblr}{hlines, vlines}1 & 2 & 3\end{tblr} \\
{Fill \\ some \\ more \\ boxes} & \usebox\SomeNumbers
\end{tblr}
\g__tblr_cell_valign_tl is altered by (the last cell of) nested tblr env.
Looks like \g__tblr_cell_valign_tl (at least as well as \g__tblr_cell_halign_tl and \g__tblr_cell_middle_tl) should be stored in a per nesting-level basis, for example in \cs{g__tblr_cell_ \int_use:N \g_tblr_level_int _prop}, and set locally.
Just a workaround: resetting cell alignments each time after a cell text is retrieved.
I still think it's better to set \g__tblr_cell_(halign|valign|middle)_tl locally (and rename them to \l__tblr_cell_...).
diff --git a/tabularray.sty b/tabularray.sty
index 15f9dd8..7f21a13 100644
--- a/tabularray.sty
+++ b/tabularray.sty
@@ -3629,7 +3629,10 @@
\dim_gzero:N \g__tblr_cell_head_dim
\dim_gzero:N \g__tblr_cell_foot_dim
}
- { \__tblr_get_cell_text_real:nn { #1 } { #2 } }
+ {
+ \__tblr_get_cell_text_real:nn { #1 } { #2 }
+ \__tblr_get_cell_alignments:nn { #1 } { #2 }
+ }
}
\tl_new:N \l__tblr_cell_fg_tl

Full example
\documentclass{article}
\usepackage[landscape]{geometry}
\usepackage{tabularray}
\SetTblrOuter{baseline=t}
\SetTblrInner{hlines, vlines}
\newsavebox\SomeNumbers
\sbox\SomeNumbers{\begin{tblr}{}1 & 2 & 3\end{tblr}}
\begin{document}
\def\test#1{
\begin{tblr}{#1}
\SetCell[c=2]{c} \texttt{\detokenize{#1}} \\
{Fill \\ some \\ boxes} &
\begin{tblr}{} 1 & 2 & 3\end{tblr} \\
{Fill \\ some \\ boxes} & \usebox\SomeNumbers
\end{tblr}
}
\def\tests{\par
\test{colspec={Q[t] Q[t]}}\quad
\test{colspec={Q[m] Q[m]}}\quad
\test{colspec={Q[b] Q[b]}}\quad
\test{colspec={Q[h] Q[h]}}\quad
\test{colspec={Q[f] Q[f]}}
}
\subsection*{Before}
\tests
\ExplSyntaxOn
\cs_gset_protected:Npn \__tblr_get_cell_text:nn #1 #2
{
\int_compare:nNnTF { \__tblr_data_item:neen { cell } {#1} {#2} { omit } } > {0}
{
\dim_gzero:N \g__tblr_cell_wd_dim
\dim_gzero:N \g__tblr_cell_ht_dim
\dim_gzero:N \g__tblr_cell_head_dim
\dim_gzero:N \g__tblr_cell_foot_dim
}
{
\__tblr_get_cell_text_real:nn { #1 } { #2 }
\__tblr_get_cell_alignments:nn { #1 } { #2 } % <<< added
}
}
\ExplSyntaxOff
\subsection*{After}
\tests
\end{document}
I don't remember why these variables were made global. They should be local because in the future we will need to make them public for hook usages.
They were changed from local to global in commit 839749e (global variables for cell alignments, 2021-04-30), prior to the first public release (2021H).
The alignment in the result image seems wrong. I think it could be better to compare subtable cells with normal text cells.
The alignment in the result image seems wrong.
If you meant the effect of colspec={Q[b] Q[b]} in both Before and After, it's probably caused by the global \SetTblrOuter{baseline=t}. Removing it and adding outer style baseline=t to the level 1 tblr env, and adding a row of normal text cells,

Full example, v2
\documentclass{article}
\usepackage[landscape]{geometry}
\usepackage{tabularray}
\SetTblrInner{hlines, vlines}
%\SetTblrOuter{baseline=t}
\newsavebox\SomeNumbers
\sbox\SomeNumbers{\begin{tblr}{}1 & 2 & 3\end{tblr}}
\begin{document}
\def\test#1{
\begin{tblr}[baseline=t]{colspec={Q[#1] Q[#1]}}
\SetCell[c=2]{c} \texttt{\detokenize{Q[#1]}} \\
{Fill \\ some \\ boxes} & text \\
{Fill \\ some \\ boxes} & \begin{tblr}{} 1 & 2 & 3\end{tblr} \\
{Fill \\ some \\ boxes} & \usebox\SomeNumbers
\end{tblr}
}
\def\tests{\par
\test{t}\quad
\test{m}\quad
\test{b}\quad
\test{h}\quad
\test{f}
}
\subsection*{Before}
\tests
\ExplSyntaxOn
\cs_gset_protected:Npn \__tblr_get_cell_text:nn #1 #2
{
\int_compare:nNnTF { \__tblr_data_item:neen { cell } {#1} {#2} { omit } } > {0}
{
\dim_gzero:N \g__tblr_cell_wd_dim
\dim_gzero:N \g__tblr_cell_ht_dim
\dim_gzero:N \g__tblr_cell_head_dim
\dim_gzero:N \g__tblr_cell_foot_dim
}
{
\__tblr_get_cell_text_real:nn { #1 } { #2 }
\__tblr_get_cell_alignments:nn { #1 } { #2 } % <<< added
}
}
\ExplSyntaxOff
\subsection*{After}
\tests
\end{document}
Just a workaround: resetting cell alignments each time after a cell text is retrieved.
[...]
diff --git a/tabularray.sty b/tabularray.sty index 15f9dd8..7f21a13 100644 --- a/tabularray.sty +++ b/tabularray.sty @@ -3629,7 +3629,10 @@ \dim_gzero:N \g__tblr_cell_head_dim \dim_gzero:N \g__tblr_cell_foot_dim } - { \__tblr_get_cell_text_real:nn { #1 } { #2 } } + { + \__tblr_get_cell_text_real:nn { #1 } { #2 } + \__tblr_get_cell_alignments:nn { #1 } { #2 } + } } \tl_new:N \l__tblr_cell_fg_tl
The patch above may be a bit confusing because I wanted to minimize the size of patch.
This v2 patch is easier to understand: set cell alignments again just after something like \hbox_set:Nn \l_tmpa_box { \__tblr_get_cell_text:nn {#1} {#2} }. If a cell contains a nested tblr table, then storing it in a temp box may change \g__tblr_cell_(halign|valign|middle)_tl (globally) whose values will be used for current cell later. Thus a resetting is needed and helpful.
v2 patch, generated with git diff -U11 to show more context
diff --git a/tabularray.sty b/tabularray.sty
index 15f9dd8..a4e996d 100644
--- a/tabularray.sty
+++ b/tabularray.sty
@@ -3606,22 +3606,23 @@
\dim_set:Nn \rightsep
{ \__tblr_data_item:nen { column } { \int_use:N \c@colnum } { rightsep } }
}
%% Measure and update natural dimensions of the row/column/cell
%% #1: row number; #2 column number; #3: width dimension;
%% #4: total height dimension; #5: head dimension; #6: foot dimension
\cs_new_protected:Npn \__tblr_measure_cell_update_sizes:nnNNNN #1 #2 #3 #4 #5 #6
{
\__tblr_get_cell_alignments:nn {#1} {#2}
\hbox_set:Nn \l_tmpa_box { \__tblr_get_cell_text:nn {#1} {#2} }
+ \__tblr_get_cell_alignments:nn {#1} {#2}
\__tblr_update_cell_size:nnNNNN {#1} {#2} #3 #4 #5 #6
\__tblr_update_row_size:nnNNN {#1} {#2} #4 #5 #6
\__tblr_update_col_size:nN {#2} #3
}
%% #1: row number, #2: column number
\cs_new_protected:Npn \__tblr_get_cell_text:nn #1 #2
{
\int_compare:nNnTF { \__tblr_data_item:neen { cell } {#1} {#2} { omit } } > {0}
{
\dim_gzero:N \g__tblr_cell_wd_dim
@@ -6579,22 +6580,23 @@
\hbox_set_to_wd:Nnn \l__tblr_a_box { \l__tblr_cell_wd_dim }
{
\tl_if_eq:NnTF \g__tblr_cell_halign_tl {j}
% cell width may be less than column width for j cells
{ \__tblr_get_cell_text:nn {#1} {#2} \hfil }
{
\tl_if_eq:NnF \g__tblr_cell_halign_tl {l} { \hfil }
\__tblr_get_cell_text:nn {#1} {#2}
\tl_if_eq:NnF \g__tblr_cell_halign_tl {r} { \hfil }
}
}
+ \__tblr_get_cell_alignments:nn {#1} {#2}
\vbox_set_to_ht:Nnn \l__tblr_b_box { \l__tblr_cell_ht_dim }
{
\tl_case:Nn \g__tblr_cell_valign_tl
{
\c__tblr_valign_m_tl
{
\vfil
\int_compare:nNnT { \lTblrCellRowSpanTl } < {2}
{
\box_set_ht:Nn \l__tblr_a_box
{ \__tblr_data_item:nen { row } {#1} { @row-upper } }
I guest we may need to solve issue #531 first.