run-llama/llama_index · error · ValueError

Cannot specify both include_tables and ignore_tables

Error message

Cannot specify both include_tables and ignore_tables

What it means

SQLDatabase (via its internal SQLWrapper) lets you scope the visible schema with either include_tables (allowlist) or ignore_tables (blocklist), but not both - the combination is ambiguous. Supplying non-empty lists for both parameters raises ValueError at construction time, before any connection introspection is reused.

Source

Thrown at llama-index-core/llama_index/core/utilities/sql_wrapper.py:60

    def __init__(
        self,
        engine: Engine,
        schema: Optional[str] = None,
        metadata: Optional[MetaData] = None,
        ignore_tables: Optional[List[str]] = None,
        include_tables: Optional[List[str]] = None,
        sample_rows_in_table_info: int = 3,
        indexes_in_table_info: bool = False,
        custom_table_info: Optional[dict] = None,
        view_support: bool = False,
        max_string_length: int = 300,
    ):
        """Create engine from database URI."""
        self._engine = engine
        self._schema = schema
        if include_tables and ignore_tables:
            raise ValueError("Cannot specify both include_tables and ignore_tables")

        self._inspector = inspect(self._engine)

        # including view support by adding the views as well as tables to the all
        # tables list if view_support is True
        self._all_tables = set(
            self._inspector.get_table_names(schema=schema)
            + (self._inspector.get_view_names(schema=schema) if view_support else [])
        )

        self._include_tables = set(include_tables) if include_tables else set()
        if self._include_tables:
            missing_tables = self._include_tables - self._all_tables
            if missing_tables:
                raise ValueError(
                    f"include_tables {missing_tables} not found in database"
                )
        self._ignore_tables = set(ignore_tables) if ignore_tables else set()

View on GitHub (pinned to afd0fef371)

Solutions

  1. Choose one strategy: keep include_tables and drop ignore_tables (or vice versa).
  2. In config-driven code, treat empty/blank values as absent: include_tables=include or None.
  3. If both lists exist logically, compute the effective allowlist yourself and pass only include_tables.

Example fix

# before
 db = SQLDatabase(engine, include_tables=['users', 'orders'], ignore_tables=['logs'])

# after
 db = SQLDatabase(engine, include_tables=['users', 'orders'])
 # or, if excluding from a known full set:
 db = SQLDatabase(engine, ignore_tables=['logs'])
Defensive patterns

Strategy: validation

Validate before calling

def resolve_table_scope(include_tables, ignore_tables):
    if include_tables and ignore_tables:
        raise ValueError('Choose include_tables OR ignore_tables, not both')
    return include_tables or None, ignore_tables or None

Type guard

def table_scope_is_exclusive(include_tables, ignore_tables) -> bool:
    return not (bool(include_tables) and bool(ignore_tables))

Try / catch

try:
    db = SQLDatabase(engine, include_tables=inc, ignore_tables=ign)
except ValueError as e:
    if 'Cannot specify both' in str(e):
        db = SQLDatabase(engine, include_tables=inc)  # allowlist wins
    else:
        raise

Prevention

When it happens

Trigger: Constructing SQLDatabase(engine, include_tables=['users'], ignore_tables=['logs']); also when config-driven code fills in both defaults (e.g. from settings that define an inclusion set and an exclusion set) rather than leaving one as None.

Common situations: Text-to-SQL pipelines configured from YAML/env where both keys are populated; refactoring from ignore-only to include-only scoping and forgetting to remove the old key; passing empty-list defaults [''] truthiness mistakes.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/5b977de6bdc8965d. Report an issue: GitHub.