iflytek/astron-agent · error · ValueError

Unable to inspect model

Error message

Unable to inspect model {model}

What it means

check_table() uses SQLAlchemy's inspect() on a SQLModel class to discover its mapped table. inspect(model) returns None when the object passed is not a mapped class (no entry in the SQLAlchemy registry), so the guard raises ValueError naming the model. This means the argument is not a valid SQLModel/SQLAlchemy declarative class.

Solutions

  1. Pass the model class itself, not an instance: check_table(MyModel), not check_table(MyModel()).
  2. Verify the argument inherits from SQLModel (or has a __tablename__/__mapper__ attribute) and that the module defining it is imported before check_table runs.
  3. If using plain Pydantic models, switch them to SQLModel so SQLAlchemy can map them, or stop calling check_table on unmapped models.
  4. Check for circular imports that prevent the model class from being fully defined/registered.

Example fix

// before
service.check_table(item_instance)          # instance, not mapped class
service.check_table(SomePlainPydanticModel) # not SQLModel
// after
from domain.models import Item  # SQLModel subclass, imported for mapper registration
service.check_table(Item)       # pass the class
Defensive patterns

Strategy: validation

Validate before calling

def is_mapped_model(m) -> bool:
    from sqlmodel import SQLModel
    return isinstance(m, type) and issubclass(m, SQLModel)

assert is_mapped_model(MyModel), "pass the SQLModel class, not an instance"

Type guard

def is_sqlmodel_class(obj) -> bool:
    import inspect as _i
    from sqlmodel import SQLModel
    return _i.isclass(obj) and issubclass(obj, SQLModel)

Try / catch

try:
    results = service.check_table(model)
except ValueError as e:
    logger.error("check_table needs a mapped SQLModel class: %s", e)

Prevention

When it happens

Trigger: Calling check_table() with a non-mapped object: a plain class not inheriting SQLModel, an instance instead of the class, a model whose mappers were not configured (e.g. SQLModel not imported/registered), or any arbitrary type such as a string or dict.

Common situations: Passing an instantiated model (check_table(MyModel())) instead of the class; typos importing the model so the real mapped class never loads; refactoring a model away from SQLModel to a dataclass/pydantic BaseModel while still calling check_table on it; circular imports leaving the model module partially initialized.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/d5035966c49b5fc9. Report an issue: GitHub.

Appendix: source

Thrown at core/plugin/link/domain/models/utils.py:175

        with Session(self.engine) as session:
            yield session

    def check_table(self, model: type[SQLModel]) -> List[Result]:
        """Check if a table and its columns exist in the database.

        Args:
            model: SQLModel class to check against database.

        Returns:
            list[Result]: List of Result objects for table and column checks.
        """
        results = []
        inspector = inspect(self.engine)

        # Use SQLAlchemy inspect() to get table name instead of private __tablename__
        model_inspector = inspect(model)
        if model_inspector is None:
            raise ValueError(f"Unable to inspect model {model}")
        table_name = model_inspector.local_table.name

        # Use modern Pydantic v2 model_fields instead of deprecated __fields__
        expected_columns = list(getattr(model, "model_fields", {}).keys())
        try:
            available_columns = [
                col["name"] for col in inspector.get_columns(table_name)
            ]
            results.append(Result(name=table_name, type="table", success=True))
        except sa.exc.NoSuchTableError:
            logger.error(f"Missing table: {table_name}")
            results.append(Result(name=table_name, type="table", success=False))
            return results

        for column in expected_columns:
            if column not in available_columns:
                logger.error(f"Missing column: {column} in table {table_name}")
                results.append(Result(name=column, type="column", success=False))

View on GitHub (pinned to 5e758547a8)