Describe the bug
Description
report() throws an error on svyglm (survey-weighted GLM) models:
Error in `UseMethod()`:
! no applicable method for 'format_value' applied to an object of class "NULL"
report_table() and report_parameters() work fine on the same model, only the full report() narrative crashes. insight::is_model_supported() returns TRUE for the model, and performance::model_performance() also works without error.
Root cause
Traceback shows the failure is in report_statistics.glm(), which builds a "t(df) = ..., p = ..." sentence for each coefficient using:
insight::format_value(params_table$df, protect_integers = TRUE)
For an ordinary glm, params_table$df (from parameters::model_parameters()) is a numeric residual-df column. For svyglm, that column comes back as NULL instead, likely because svyglm uses design-based Wald tests rather than classical residual df, and parameters::model_parameters.svyglm() doesn't populate a df column the same way. report_statistics.glm() assumes df is always present (since svyglm inherits class glm), so passing NULL into insight::format_value() breaks, since that function has no default/NULL method.
Full traceback
▆
1. ├─report::report(convergence_model)
2. └─report:::report.glm(convergence_model)
3. ├─report::report_text(x, table = result_table, ...)
4. └─report:::report_text.glm(x, table = result_table, ...)
5. ├─report::report_parameters(...)
6. └─report:::report_parameters.glm(...)
7. ├─report::report_statistics(...)
8. └─report:::report_statistics.glm(...)
9. ├─datawizard::text_paste(...)
10. ├─base::paste0(...)
11. └─insight::format_value(params_table$df, protect_integers = TRUE)
Expected behavior
report() should either report a Wald z-statistic instead of t(df) when residual df is unavailable, or fail gracefully with an informative message, rather than throwing an uncaught format_value(NULL) error.
Suggested fixes
Either (or both) would resolve this:
- In
report_statistics.glm(), fall back to a Wald z-statistic sentence ("z = ..., p = ...") when df is NULL/unavailable, mirroring how summary.svyglm() itself reports results without residual df in some designs.
- In
insight::format_value(), add a trivial method (or an early NULL check) that returns NA/an empty string instead of erroring, since a NULL propagating into a formatting function generically represents a missing value rather than a hard failure.
Reproducible example
r
library(survey)
#> Loading required package: grid
#> Loading required package: Matrix
#> Loading required package: survival
#>
#> Attaching package: 'survey'
#> The following object is masked from 'package:graphics':
#>
#> dotchart
library(srvyr)
#>
#> Attaching package: 'srvyr'
#> The following object is masked from 'package:stats':
#>
#> filter
library(report)
data(api)
dstrata <- apistrat %>% as_survey_design(strata = stype, weights = pw)
convergence_model <- svyglm(
sch.wide ~ stype * yr.rnd,
design = dstrata,
family = binomial()
)
#> Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Inspect the parameters table report_statistics.glm() operates on:
params_table <- parameters::model_parameters(convergence_model)
params_table$df # NULL here — ordinary glm objects have a numeric df column
#> [1] 192 192 192 192 192 192
# Works fine — doesn't go through report_statistics.glm()'s t(df) sentence:
report::report_table(convergence_model)
#> Warning in eval(family$initialize): non-integer #successes in a binomial glm!
#> Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
#> Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
#> Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
#> Parameter | Coefficient | 95% CI | t | p
#> --------------------------------------------------------------------------
#> (Intercept) | 2.22 | [ 1.49, 2.96] | 5.95 | < .001
#> stype [H] | -2.10 | [ -3.03, -1.17] | -4.45 | < .001
#> stype [M] | -1.34 | [ -2.31, -0.37] | -2.71 | 0.007
#> yr rnd [Yes] | 0.61 | [ -1.56, 2.78] | 0.55 | 0.581
#> stype [H] × yr rnd [Yes] | -15.09 | [-18.07, -12.10] | -9.96 | < .001
#> stype [M] × yr rnd [Yes] | -1.50 | [ -5.11, 2.12] | -0.82 | 0.415
#> | | | |
#> AIC | | | |
#> AICc | | | |
#> BIC | | | |
#> R2 | | | |
#> R2 (adj.) | | | |
#> Sigma | | | |
#> Log_loss | | | |
#>
#> Parameter | Std. Coef. | Std. Coef. 95% CI | Fit
#> ------------------------------------------------------------------
#> (Intercept) | 2.22 | [ 1.49, 2.96] |
#> stype [H] | -2.10 | [ -3.03, -1.17] |
#> stype [M] | -1.34 | [ -2.31, -0.37] |
#> yr rnd [Yes] | 0.61 | [ -1.56, 2.78] |
#> stype [H] × yr rnd [Yes] | -15.09 | [-18.07, -12.10] |
#> stype [M] × yr rnd [Yes] | -1.50 | [ -5.11, 2.12] |
#> | | |
#> AIC | | | 166.27
#> AICc | | | 203.20
#> BIC | | | 225.71
#> R2 | | | 0.14
#> R2 (adj.) | | | 0.10
#> Sigma | | | 1.00
#> Log_loss | | | 0.47
# Crashes:
report::report(convergence_model)
#> Warning in eval(family$initialize): non-integer #successes in a binomial glm!
#> Warning in eval(family$initialize): svyglm not fitted by maximum likelihood.
#> Warning in eval(family$initialize): svyglm not fitted by maximum likelihood.
#> Warning in eval(family$initialize): svyglm not fitted by maximum likelihood.
#> Error in `UseMethod()`:
#> ! no applicable method for 'format_value' applied to an object of class "NULL"
<sup>Created on 2026-09-04 with [reprex v2.1.1](https://reprex.tidyverse.org)</sup>
<details style="margin-bottom:10px;">
<summary>
Session info
</summary>
r
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#> setting value
#> version R version 4.6.1 (2026-06-24 ucrt)
#> os Windows 11 x64 (build 26100)
#> system x86_64, mingw32
#> ui RTerm
#> language (EN)
#> collate English_United States.utf8
#> ctype English_United States.utf8
#> tz Europe/Berlin
#> date 2026-09-04
#> pandoc 3.10 @ c:\\Users\\mpo25\\AppData\\Local\\Programs\\Positron\\resources\\app\\quarto\\bin\\tools/ (via rmarkdown)
#> quarto NA
#>
#> ─ Packages ───────────────────────────────────────────────────────────────────
#> package * version date (UTC) lib source
#> bayestestR 0.17.0 2025-08-29 [1] CRAN (R 4.6.0)
#> cli 3.6.6 2026-04-09 [1] CRAN (R 4.6.0)
#> coda 0.19-4.1 2024-01-31 [1] CRAN (R 4.6.0)
#> datawizard 1.3.1 2026-04-26 [1] CRAN (R 4.6.0)
#> DBI 1.3.0 2026-02-25 [1] CRAN (R 4.6.0)
#> digest 0.6.39 2025-11-19 [1] CRAN (R 4.6.0)
#> dplyr 1.2.1 2026-04-03 [1] CRAN (R 4.6.0)
#> effectsize 1.0.2 2026-03-11 [1] CRAN (R 4.6.0)
#> emmeans 2.0.4 2026-07-15 [1] CRAN (R 4.6.1)
#> estimability 1.5.1 2024-05-12 [1] CRAN (R 4.6.0)
#> evaluate 1.0.5 2025-08-27 [1] CRAN (R 4.6.0)
#> fastmap 1.2.0 2024-05-15 [1] CRAN (R 4.6.0)
#> fs 2.1.0 2026-04-18 [1] CRAN (R 4.6.0)
#> generics 0.1.4 2025-05-09 [1] CRAN (R 4.6.0)
#> glue 1.8.1 2026-04-17 [1] CRAN (R 4.6.0)
#> htmltools 0.5.9 2025-12-04 [1] CRAN (R 4.6.0)
#> insight 1.5.0 2026-04-14 [1] CRAN (R 4.6.0)
#> knitr 1.51 2025-12-20 [1] CRAN (R 4.6.0)
#> lattice 0.22-9 2026-02-09 [2] CRAN (R 4.6.1)
#> lifecycle 1.0.5 2026-01-08 [1] CRAN (R 4.6.0)
#> magrittr 2.0.5 2026-04-04 [1] CRAN (R 4.6.0)
#> Matrix * 1.7-5 2026-03-21 [2] CRAN (R 4.6.1)
#> mitools 2.4 2019-04-26 [1] CRAN (R 4.6.0)
#> mvtnorm 1.3-7 2026-04-15 [1] CRAN (R 4.6.0)
#> otel 0.2.0 2025-08-29 [1] CRAN (R 4.6.0)
#> parameters 0.29.0 2026-05-09 [1] CRAN (R 4.6.0)
#> performance 0.16.0 2026-02-04 [1] CRAN (R 4.6.0)
#> pillar 1.11.1 2025-09-17 [1] CRAN (R 4.6.0)
#> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.6.0)
#> purrr 1.2.2 2026-04-10 [1] CRAN (R 4.6.0)
#> R6 2.6.1 2025-02-15 [1] CRAN (R 4.6.0)
#> Rcpp 1.1.2 2026-07-05 [1] CRAN (R 4.6.1)
#> report * 0.6.4 2026-05-04 [1] CRAN (R 4.6.0)
#> reprex 2.1.1 2024-07-06 [1] CRAN (R 4.6.1)
#> rlang 1.2.0 2026-04-06 [1] CRAN (R 4.6.0)
#> rmarkdown 2.31 2026-03-26 [1] CRAN (R 4.6.0)
#> sessioninfo 1.2.4 2026-06-04 [1] CRAN (R 4.6.0)
#> srvyr * 1.3.1 2026-02-02 [1] CRAN (R 4.6.0)
#> survey * 4.5 2026-02-24 [1] CRAN (R 4.6.0)
#> survival * 3.8-6 2026-01-16 [2] CRAN (R 4.6.1)
#> tibble 3.3.1 2026-01-11 [1] CRAN (R 4.6.0)
#> tidyr 1.3.2 2025-12-19 [1] CRAN (R 4.6.0)
#> tidyselect 1.2.1 2024-03-11 [1] CRAN (R 4.6.0)
#> vctrs 0.7.3 2026-04-11 [1] CRAN (R 4.6.0)
#> withr 3.0.3 2026-06-19 [1] CRAN (R 4.6.0)
#> xfun 0.59 2026-06-19 [1] CRAN (R 4.6.0)
#> xtable 1.8-8 2026-02-22 [1] CRAN (R 4.6.0)
#> yaml 2.3.12 2025-12-10 [1] CRAN (R 4.6.0)
#>
#> [1] C:/Users/mpo25/AppData/Local/R/win-library/4.6
#> [2] C:/Program Files/R/R-4.6.1/library
#> * ── Packages attached to the search path.
#>
#> ──────────────────────────────────────────────────────────────────────────────
</details>
Describe the bug
Description
report()throws an error onsvyglm(survey-weighted GLM) models:report_table()andreport_parameters()work fine on the same model, only the fullreport()narrative crashes.insight::is_model_supported()returnsTRUEfor the model, andperformance::model_performance()also works without error.Root cause
Traceback shows the failure is in
report_statistics.glm(), which builds a"t(df) = ..., p = ..."sentence for each coefficient using:For an ordinary
glm,params_table$df(fromparameters::model_parameters()) is a numeric residual-df column. Forsvyglm, that column comes back asNULLinstead, likely becausesvyglmuses design-based Wald tests rather than classical residual df, andparameters::model_parameters.svyglm()doesn't populate adfcolumn the same way.report_statistics.glm()assumesdfis always present (sincesvyglminherits classglm), so passingNULLintoinsight::format_value()breaks, since that function has no default/NULL method.Full traceback
Expected behavior
report()should either report a Wald z-statistic instead oft(df)when residual df is unavailable, or fail gracefully with an informative message, rather than throwing an uncaughtformat_value(NULL)error.Suggested fixes
Either (or both) would resolve this:
report_statistics.glm(), fall back to a Wald z-statistic sentence ("z = ..., p = ...") whendfisNULL/unavailable, mirroring howsummary.svyglm()itself reports results without residual df in some designs.insight::format_value(), add a trivial method (or an earlyNULLcheck) that returnsNA/an empty string instead of erroring, since aNULLpropagating into a formatting function generically represents a missing value rather than a hard failure.Reproducible example