Skip to content

fix: avoid panics on Jinja-templated SQL with config()/source() blocks#2571

Open
kimfrie wants to merge 1 commit into
quarylabs:mainfrom
kimfrie:fix/2464-reflow-indent-templated-newlines
Open

fix: avoid panics on Jinja-templated SQL with config()/source() blocks#2571
kimfrie wants to merge 1 commit into
quarylabs:mainfrom
kimfrie:fix/2464-reflow-indent-templated-newlines

Conversation

@kimfrie
Copy link
Copy Markdown

@kimfrie kimfrie commented Apr 20, 2026

Summary

  • Fixes the Option::unwrap() on a None value panic at crates/lib/src/utils/reflow/elements.rs:272 that occurs when every newline in a ReflowPoint comes from a Jinja template block (e.g. the source combines {{ config(...) }} with {{ ref() }} / {{ source() }} on a referenced table).
  • When no literal newline exists in the point, indent_to now emits no fix and returns the point unchanged, rather than crashing the linter run.
  • Also hardens the inner get_position_marker().unwrap() used while matching the literal newline.

Fixes #2464.

Reproduction

Using the minimal example from #2464 (dbt templater, bigquery dialect):

{{ config(materialized='table') }}

with raw_data as (
    select * from {{ source('conn', 'tbl') }}
               )
select *
from raw_data

Before: thread '<unnamed>' panicked at crates/lib/src/utils/reflow/elements.rs:272:22: called Option::unwrap() on a None value.
After: linter completes with ordinary LT-rule violations, no panic.

Verified locally against 12 real-world dbt/jinja models (redshift dialect, apply_dbt_builtins = True) that each reproduced the panic on sqruff 0.37.3 — all now lint cleanly.

Test plan

  • cargo test --release --features python -p sqruff-lib --lib reflow — all 10 reflow tests pass
  • Manually re-linted 12 files from a downstream project; 0 panics vs. dozens previously

🤖 Generated with Claude Code

`ReflowPoint::indent_to` (crates/lib/src/utils/reflow/elements.rs)
walks backwards through segments to find the last *literal* newline to
anchor a whitespace fix on. When every newline came from a Jinja
template block (e.g. `{{ config(...) }}` combined with `{{ ref() }}` /
`{{ source() }}` on a referenced table), no literal newline exists
and the `unwrap()` panicked with `Option::unwrap() on a None value`
at `elements.rs:272`. Return no-fix instead.

Once that panic is gone, `fix` (not `lint`) surfaces a second panic
in `ErasedSegment::iter_patches` (crates/lib-core/src/parser/segments.rs)
with `begin > end (788 > 609) when slicing source_str` — a literal
segment with a malformed source/templated slice. Skip the patch when
the slice is invalid rather than panicking.

Verified against 13 real-world dbt/jinja models (redshift dialect,
`apply_dbt_builtins = True`) that previously panicked 11–60× per file
under sqruff 0.37.3: all now lint cleanly and `fix` completes.

Fixes quarylabs#2464
@kimfrie kimfrie force-pushed the fix/2464-reflow-indent-templated-newlines branch from 20485e8 to 30bc3e4 Compare April 27, 2026 07:09
@kimfrie kimfrie changed the title fix(reflow): avoid panic in indent_to when all newlines are templated fix: avoid panics on Jinja-templated SQL with config()/source() blocks Apr 27, 2026
@kimfrie
Copy link
Copy Markdown
Author

kimfrie commented May 26, 2026

@benfdking would you help me with a review?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Unexpected Exception

1 participant