#8428·sqlfluff

A .sqlfluffignore in a subdirectory is ignored one level down when the path is relative

Author: devYRPauliCreated Sep 2, 2026Updated Sep 3, 2026

Search before asking

  • I searched the issues and found no similar issues.

What Happened

A .sqlfluffignore file in a subdirectory stops applying one level below itself when the path on the command line is relative. sqlfluff lint . lints the ignored files, and sqlfluff fix . rewrites them.

The same tree behaves correctly when you pass an absolute path.

Expected Behaviour

A .sqlfluffignore file applies to every file below its own directory, as docs/source/configuration/ignoring_configuration.rst describes. The result must not depend on whether the path argument is relative or absolute.

Observed Behaviour

sub/deeper/b.sql is linted and fixed, although sub/.sqlfluffignore holds *.sql.

$ sqlfluff lint .
== [sub/deeper/b.sql] FAIL
L:   1 | P:   7 | LT01 | Expected only single space before numeric literal. Found
                       | '    '. [layout.spacing]
L:   1 | P:  12 | LT01 | Expected only single space before 'from' keyword. Found
                       | '   '. [layout.spacing]
L:   1 | P:  15 | CP01 | Keywords must be consistently upper case.
                       | [capitalisation.keywords]
All Finished!

$ sqlfluff lint /tmp/sfign/proj
All Finished!

sqlfluff fix . then writes the ignored file:

$ cat sub/deeper/b.sql
SELECT    3   from t
$ sqlfluff fix . --force
== [sub/deeper/b.sql] FIXED
3 fixable linting violations found
$ cat sub/deeper/b.sql
SELECT 3 FROM t

The cause is in src/sqlfluff/core/linter/discovery.py:199-203:

python
if not (
    dirname == inner_dirname
    or dirname.startswith(os.path.abspath(inner_dirname) + os.sep)
):
    inner_ignore_specs.remove((inner_dirname, inner_file, inner_spec))

dirname and inner_dirname both come from the same os.walk(path), so both are relative when path is relative. Only the right side is made absolute. The startswith test is then always false and the spec is dropped as soon as the walk descends one level. The dirname == inner_dirname branch still holds, so a file in the same directory as the ignore file is ignored correctly. Only the levels below it leak.

How to reproduce

mkdir -p /tmp/sfign/proj/sub/deeper
cd /tmp/sfign/proj
printf '[sqlfluff]\ndialect = ansi\n' > .sqlfluff
printf '*.sql\n' > sub/.sqlfluffignore
printf 'SELECT 1\n' > top.sql
printf 'SELECT 2\n' > sub/a.sql
printf 'SELECT    3   from t\n' > sub/deeper/b.sql

sqlfluff lint .                 # lists sub/deeper/b.sql, wrong
sqlfluff lint /tmp/sfign/proj   # lists top.sql only, correct

Directly on the discovery function:

python
>>> from sqlfluff.core.linter.discovery import paths_from_path
>>> sorted(paths_from_path("."))
['sub/deeper/b.sql', 'top.sql']
>>> sorted(paths_from_path("/tmp/sfign/proj"))
['/tmp/sfign/proj/top.sql']

sub/a.sql sits next to the ignore file and is ignored in both runs.

Dialect

ansi. The defect is in path discovery, so every dialect is affected.

Version

sqlfluff, version 4.3.0
Python 3.12.12

Introduced in 16006dd0f (#6080).

Configuration

/tmp/sfign/proj/.sqlfluff:

[sqlfluff]
dialect = ansi

/tmp/sfign/proj/sub/.sqlfluffignore:

*.sql

Are you willing to work on and submit a PR to address the issue?

  • Yes I am willing to submit a PR!

Code of Conduct