astral-sh/ruff · error

Cannot insert `TYPE_CHECKING` block inline

Error message

Cannot insert `TYPE_CHECKING` block inline

What it means

The importer builds an edit to insert an `if TYPE_CHECKING:` block plus the typing import when a fix moves an import into a type-checking block. If the computed insertion point is inline (attached to an existing statement rather than start-of-file or a standalone line), the fixer cannot place the block correctly and returns this error instead of producing a broken edit.

Source

Thrown at crates/ruff_linter/src/importer/mod.rs:514

            comma: aliases.last().and_then(|alias| alias.comma.clone()),
        });
        Ok(Edit::range_replacement(
            statement.codegen_stylist(self.stylist),
            stmt.range(),
        ))
    }

    /// Add a `TYPE_CHECKING` block to the given module.
    fn add_type_checking_block(&self, content: &str, at: TextSize) -> Result<Edit> {
        let insertion = if let Some(stmt) = self.preceding_import(at) {
            // Insert after the last top-level import.
            Insertion::end_of_statement(stmt, self.source, self.stylist)
        } else {
            // Insert at the start of the file.
            Insertion::start_of_file(self.python_ast, self.source, self.stylist, None)
        };
        if insertion.is_inline() {
            Err(anyhow::anyhow!(
                "Cannot insert `TYPE_CHECKING` block inline"
            ))
        } else {
            Ok(insertion.into_edit(content))
        }
    }

    /// Add an import statement to an existing `TYPE_CHECKING` block.
    fn add_to_type_checking_block(&self, content: &str, at: TextSize) -> Edit {
        Insertion::start_of_block(at, self.source, self.stylist, self.tokens).into_edit(content)
    }

    /// Return the import statement that precedes the given position, if any.
    fn preceding_import(&self, at: TextSize) -> Option<&'a Stmt> {
        self.runtime_imports
            .partition_point(|stmt| stmt.start() < at)
            .checked_sub(1)
            .map(|idx| self.runtime_imports[idx])

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Apply the fix without requiring the TYPE_CHECKING block (disable the specific rule or fix) and move the import manually.
  2. Normalize the file so it starts with plain statements (remove exotic continuation constructs at the top) and re-run `ruff check --fix`.
  3. Manually add `from typing import TYPE_CHECKING` and the `if TYPE_CHECKING:` block, then re-run to let other fixes apply.

Example fix

// before (file starts with a backslash continuation; fixer cannot insert inline)
\
import foo

// after (manual restructure so the block can be inserted)
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    import foo
Defensive patterns

Strategy: try-catch

Try / catch

match fixer.apply_fix() {
    Err(e) if e.to_string().contains("Cannot insert `TYPE_CHECKING` block inline") => {
        eprintln!("Apply this fix manually or restructure the file's top statements");
    }
    other => other?,
}

Prevention

When it happens

Trigger: A fix using `TypingImportEdit::add_type_checking_block` where the target file's context yields an inline insertion (e.g. the file starts mid-statement or the only insertion point is inline).

Common situations: Files beginning with a line-continuation/backslash continuation, obscure start-of-file constructs, or autofix attempts on syntactically unusual prologues where a top-level block cannot be inserted cleanly.

Related errors


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/e8aa222393fdc313. Report an issue: GitHub.