Error codes¶
Every refusal of py2axum names what is not supported, at file:line, with a stable code. The code tells why and what to do; py2axum check --explain CODE prints the same text in a terminal:
error[P2A0201]: app/routers/export.py:26: library call `zipfile.ZipFile()` is not supported (not in the py2axum library map)
= why: The call goes to a library the binary has no equivalent for: py2axum maps a closed list of ...
= help: Use a supported library or the standard library for the same job (see Libraries and ...
= see: https://larrymotalavigne.github.io/py2axum/reference/errors/#p2a0201
Codes are stable: a code always names the same class of refusal, and a retired code is never reused. Classes marked whole application refuse the generation whatever the routes: --python-side auto cannot move them to Python.
| Code | Class |
|---|---|
| P2A0101 | Python construct not supported |
| P2A0102 | global/nonlocal |
| P2A0103 | /* expansion |
| P2A0104 | Builtin not supported |
| P2A0105 | Unknown name or import |
| P2A0106 | Value not known at translation time |
| P2A0107 | Loop with else |
| P2A0108 | Call signature |
| P2A0109 | async/await |
| P2A0110 | Module-level statement |
| P2A0111 | Project class |
| P2A0112 | Dataclass |
| P2A0113 | Enum class |
| P2A0114 | match statement |
| P2A0115 | Syntax error |
| P2A0116 | Decorator |
| P2A0117 | Python 3.14 or 3.15 construct not supported |
| P2A0118 | Synchronous generator consumed synchronously |
| P2A0201 | Library call not supported |
| P2A0202 | Library value not supported |
| P2A0203 | Method not implemented by the runtime |
| P2A0204 | Attribute not provided by the runtime |
| P2A0205 | Keyword option not supported |
| P2A0206 | Library exception class |
| P2A0207 | MCP server construct not supported |
| P2A0208 | Logging construct not supported |
| P2A0209 | Option not supported |
| P2A0301 | Application method or decorator |
| P2A0302 | Middleware not supported |
| P2A0303 | Lifespan or startup event |
| P2A0304 | Router registration |
| P2A0305 | Route or response option |
| P2A0306 | Endpoint parameter |
| P2A0307 | Dependency |
| P2A0308 | Security scheme |
| P2A0309 | WebSocket route |
| P2A0310 | app.mount() |
| P2A0311 | FastAPI() option |
| P2A0312 | Registration outside the app factory |
| P2A0313 | Exception handler |
| P2A0314 | Nested endpoint |
| P2A0401 | Type annotation |
| P2A0402 | Field option |
| P2A0403 | Pydantic validator |
| P2A0404 | Model configuration |
| P2A0405 | Pydantic decorator |
| P2A0406 | Model class body |
| P2A0407 | Annotated metadata |
| P2A0408 | JSON schema |
| P2A0410 | Enum or non-Pydantic type |
| P2A0501 | Column type |
| P2A0502 | Column declaration |
| P2A0503 | Mapped class declaration |
| P2A0504 | Relationship |
| P2A0505 | Session or engine |
| P2A0506 | SQL statement |
| P2A0507 | create_all and DDL |
| P2A0508 | TypeDecorator |
| P2A0509 | Table introspection |
| P2A0510 | Alembic migrations |
| P2A0601 | Library version outside the tested ranges |
| P2A0602 | Cannot be left to Python |
| P2A0603 | Not available on the project's Python |
| P2A0901 | Internal transpiler error |
| P2A0999 | Not supported |
Python language¶
P2A0101¶
Python construct not supported
py2axum compiles a subset of Python; this construct has no equivalent in the runtime yet.
What to do: Rewrite it with a supported construct (see Python semantics). If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See Python semantics.
P2A0102¶
global/nonlocal
Module state rebound from functions is reproduced for variables assigned at module level only; nonlocal rebinds a local variable of the enclosing function, not one of its parameters.
What to do: Assign the variable at module level and rebind it with global in the module that defines it; for nonlocal, copy the parameter into a local variable first.
See Python semantics.
P2A0103¶
/ expansion*
Calls and signatures are resolved statically; this expansion cannot be.
What to do: Pass the arguments explicitly.
See Python semantics.
P2A0104¶
Builtin not supported
This builtin, or this use of it, has no equivalent in the runtime.
What to do: Use a supported builtin (see Python semantics).
See Python semantics.
P2A0105¶
Unknown name or import
py2axum resolves every name statically, over the project and the libraries it knows; this one does not resolve.
What to do: Import the name from a module of the project or of a supported library, with a literal import.
See Python semantics.
P2A0106¶
Value not known at translation time
py2axum reads configuration (options, types, routes) without running the project: this value must be written literally or computed by something py2axum evaluates.
What to do: Write the value itself (a literal, or a module constant assigned once).
See How it works.
P2A0107¶
Loop with else
else clauses of loops are not compiled.
What to do: Use a flag variable or a helper function that returns.
See Python semantics.
P2A0108¶
Call signature
The call does not match the function's signature, or uses a form py2axum cannot bind statically: Python would raise a TypeError or behave in a way that is not reproduced.
What to do: Call the function with the arguments the message lists.
See Python semantics.
P2A0109¶
async/await
A coroutine that is not awaited directly (stored, passed around) is not reproduced.
What to do: await the call where it is made, or use asyncio.create_task/gather on direct calls.
See Python semantics.
P2A0110¶
Module-level statement — whole application
Module code runs once at startup in the binary; only statements py2axum can reproduce there are translated.
What to do: Move the computation into a function, or assign the variable once at module level.
See Python semantics.
P2A0111¶
Project class
Project classes are compiled when they are models, schemas, exceptions, dataclasses, enums or plain classes with plain methods; this member or form is not reproduced.
What to do: Keep the class to __init__, plain methods and properties, or turn it into a dataclass or a model.
See Python semantics.
P2A0112¶
Dataclass
Dataclasses are compiled with plain fields, field(default=, default_factory=) and methods.
What to do: Keep the dataclass to fields and plain methods, without options or base classes.
See Python semantics.
P2A0113¶
Enum class
Enums are compiled with literal member values and plain methods.
What to do: Use literal member values, no Flag/IntFlag, no subclassing.
See Python semantics.
P2A0114¶
match statement
Only some pattern kinds of match are compiled.
What to do: Use the supported patterns (values, None/True/False, _, names, Class(), |, as) or if/elif.
See Python semantics.
P2A0115¶
Syntax error — whole application
The file does not parse with the Python running py2axum.
What to do: Fix the syntax, or run py2axum on a Python at least as recent as the project's (Python 3.14 syntax such as except A, B: needs py2axum on 3.14).
See Versions.
P2A0116¶
Decorator
Decorators are applied at translation time; only the decorators py2axum knows are reproduced.
What to do: Remove the decorator or use a supported one (see Python semantics). If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See Python semantics.
P2A0117¶
Python 3.14 or 3.15 construct not supported
A construct of a recent Python (template strings, lazy imports of project modules) has no equivalent in the runtime yet, or would change when the module's top-level code runs.
What to do: Use the construct the message suggests (an f-string, a plain import).
See python-versions.md.
P2A0118¶
Synchronous generator consumed synchronously
The runtime runs a generator function as an async generator: a streamed response consumes it like Starlette, a synchronous consumer (list(), for, next(), a comprehension) cannot drive it lazily.
What to do: Build the list in the function and return it, or write an async def generator iterated with async for.
See Python semantics.
Libraries¶
P2A0201¶
Library call not supported
The call goes to a library the binary has no equivalent for: py2axum maps a closed list of library functions to its runtime and never calls Python libraries from the binary.
What to do: Use a supported library or the standard library for the same job (see Libraries and Standard library). If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See Libraries.
P2A0202¶
Library value not supported
A value of a library outside py2axum's library map is read (a constant, a class used as a value...).
What to do: Read it from a supported library or write the value itself. If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See Libraries.
P2A0203¶
Method not implemented by the runtime
No value type of the runtime has this method, and no project class defines it: the binary would fail with a 500 where Python runs it.
What to do: Use a supported method of the value (see Python semantics), or check the receiver's type: it may be a value py2axum does not model. If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See Python semantics.
P2A0204¶
Attribute not provided by the runtime
No value type of the runtime has this attribute, and no project class defines it.
What to do: Read a supported attribute, or keep the value in a project class or a Pydantic model. If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See Python semantics.
P2A0205¶
Keyword option not supported
The function is supported, but not with this keyword argument: its behaviour with it is not reproduced.
What to do: Drop the option or use one of the supported options listed in the message. If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See Standard library.
P2A0206¶
Library exception class
except or raise names an exception class of a library the runtime does not model.
What to do: Catch a supported exception (the library's documented base class, or a project exception). If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See Python semantics.
P2A0207¶
MCP server construct not supported
py2axum compiles the stateless, JSON-response subset of the MCP SDK's server (tools only).
What to do: Write tools as async def with @server.tool() and serve streamable_http_app(stateless_http=True, json_response=True). If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See MCP servers.
P2A0208¶
Logging construct not supported
The binary reproduces the logging module as the applications use it (see Logging): a record carries the call site itself, and only the standard handlers and formatters exist.
What to do: Log from the function whose location you want in the record (or drop stacklevel=); use StreamHandler, FileHandler, NullHandler and logging.Formatter or python-json-logger. If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See advanced/logging.md.
P2A0209¶
Option not supported
The function or class is supported, but not with this option: its effect is not reproduced.
What to do: Drop the option, or use one of the supported options listed in the message. If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See Supported subset.
FastAPI and Starlette¶
P2A0301¶
Application method or decorator — whole application
This method of the FastAPI application has no equivalent in the binary.
What to do: See the supported subset for the application methods the binary reproduces; register the same thing with a supported form, or leave the part that needs it to Python.
See Supported subset.
P2A0302¶
Middleware not supported — whole application
Middlewares are compiled one by one: GZip, CORS, TrustedHost, HTTPSRedirect, project BaseHTTPMiddleware subclasses and raw ASGI middlewares of the project, with literal options.
What to do: Use one of the supported middlewares with literal keyword options. A middleware of a library must stay in Python: the whole application then runs in Python (a middleware wraps every route).
See Middleware.
P2A0303¶
Lifespan or startup event
Startup and shutdown code is compiled when it uses supported constructs; this form is not.
What to do: Use FastAPI(lifespan=...) with an @asynccontextmanager and module globals, or leave it to Python with --python-side lifespan.
See Lifespan events.
P2A0304¶
Router registration — whole application
Routes are discovered statically: py2axum must know at translation time which routes exist and under which prefix.
What to do: Call include_router unconditionally, at module level or at the top level of the app factory, with a literal prefix or one read from settings.
See Bigger applications.
P2A0305¶
Route or response option
This option of the route decorator changes the response in a way the binary does not reproduce.
What to do: Use the supported response classes and options (see Responses), or return a response object.
See Responses.
P2A0306¶
Endpoint parameter
FastAPI decides from each parameter's annotation and default where its value comes from; this one cannot be decided statically or is not reproduced.
What to do: Annotate the parameter with a supported type and Query(), Path(), Header(), Cookie(), Body(), Form() or File().
See Parameters.
P2A0307¶
Dependency
Dependencies are compiled when they are project functions (sync, async, generators with one yield), Pydantic models, plain classes or instances with __call__.
What to do: Wrap the library object in a project function: def get_x(): return lib.X() and Depends(get_x).
See Dependencies.
P2A0308¶
Security scheme
Only OAuth2PasswordBearer, HTTPBearer and HTTPBasic are compiled, with literal options.
What to do: Use one of these schemes (they cover Bearer tokens and Basic auth), with literal keyword options.
See Security.
P2A0309¶
WebSocket route
This WebSocket construct is not reproduced (the binary implements Starlette's WebSocket protocol).
What to do: Use @app.websocket(path) with an async def endpoint and the parameters FastAPI provides on a WebSocket route. WebSocket routes are never relayed to Python.
See WebSockets.
P2A0310¶
app.mount()
A mounted sub-application is not compiled; as the app's last registrations, mounts can stay in Python.
What to do: Register mounts last and pass --python-side mount (implied by --python-side auto).
See Bigger applications.
P2A0311¶
FastAPI() option — whole application
This option of the FastAPI constructor is not reproduced, or not with a computed value.
What to do: Pass the option as a literal, or drop it if it only affects OpenAPI documentation.
See Supported subset.
P2A0312¶
Registration outside the app factory — whole application
Routes, middlewares and handlers must be registered where py2axum can read them without running code.
What to do: Move the registration to module level or to the top level of the app factory function.
See Bigger applications.
P2A0313¶
Exception handler — whole application
This form of exception handler registration is not reproduced.
What to do: Register handlers with @app.exception_handler(Exc) or app.add_exception_handler(Exc, handler) at module level or at the top level of the app factory.
See Handling errors.
P2A0314¶
Nested endpoint
Endpoints are compiled as functions of the generated crate: they must be defined at module level.
What to do: Define the endpoint at module level (or at the top level of the app factory).
See Bigger applications.
Pydantic¶
P2A0401¶
Type annotation
The annotation decides validation and serialisation; this type has no equivalent in the runtime's port of pydantic-core.
What to do: Use a supported type (see Models): builtins, list/dict/tuple, unions, Literal, enums, models, datetime types, UUID, Decimal, EmailStr...
See Models (Pydantic).
P2A0402¶
Field option
This Field() option or constraint is not reproduced on this type.
What to do: Use the supported options (see Models) or a validator.
See Models (Pydantic).
P2A0403¶
Pydantic validator
Validators run inside the runtime's port of pydantic-core; this signature or mode is not reproduced.
What to do: Write @field_validator('f') (mode after or before) as a classmethod taking (cls, v) or (cls, v, info).
See Models (Pydantic).
P2A0404¶
Model configuration
This configuration option changes validation or serialisation in a way the runtime does not reproduce.
What to do: Use model_config = ConfigDict(...) with supported literal options.
See Models (Pydantic).
P2A0405¶
Pydantic decorator
This Pydantic decorator is not reproduced in this form.
What to do: Use the supported forms (see Models).
See Models (Pydantic).
P2A0406¶
Model class body
Model classes are compiled from their fields, validators and simple methods; this member is not reproduced.
What to do: Keep the model to fields, model_config, validators, @property and plain methods.
See Models (Pydantic).
P2A0407¶
Annotated metadata
Pydantic validates or serialises the field differently with this metadata; py2axum never ignores metadata it does not know.
What to do: Use Field(...) constraints or a supported validator instead.
See Models (Pydantic).
P2A0408¶
JSON schema
The JSON schema of the model is computed statically, as Pydantic would; this model cannot be.
What to do: Avoid self-referencing models and duplicate model names in one schema.
See Models (Pydantic).
P2A0410¶
Enum or non-Pydantic type
Models, parameters and bodies are validated like Pydantic; only Pydantic models, enums, dataclasses and the supported scalar types can be validated.
What to do: Turn the class into a BaseModel (or a dataclass), or use a supported type.
See Models (Pydantic).
SQLAlchemy¶
P2A0501¶
Column type
The column type decides how values are bound and decoded; this one has no mapping in the runtime.
What to do: Use a supported column type (String, Integer, Numeric, Boolean, Date/DateTime, JSON/JSONB, Uuid, Enum of a Python enum class, LargeBinary, ARRAY(String)).
See SQL databases.
P2A0502¶
Column declaration
This column declaration or option is not reproduced.
What to do: Declare the column as name: Mapped[T] = mapped_column(...) with literal options.
See SQL databases.
P2A0503¶
Mapped class declaration
This declaration of a mapped class changes the SQL SQLAlchemy emits in a way the runtime does not reproduce.
What to do: Declare plain mapped classes: one table each, a single primary key, columns and relationships, @property/@staticmethod/@classmethod methods.
See SQL databases.
P2A0504¶
Relationship
This relationship() configuration changes which SQL is emitted in a way the runtime does not reproduce.
What to do: Use the supported options (back_populates, foreign_keys, lazy='select'|'selectin'|'joined'|'raise', cascade, order_by, self-referential remote_side, secondary= a module-level Table(name, metadata, Column(...), ...) without back_populates/backref or cascades).
See SQL databases.
P2A0505¶
Session or engine
The session dependency fixes when the binary commits and rolls back; this form cannot be read statically.
What to do: Use a module-level async_sessionmaker(engine, ...) (or sessionmaker) and a dependency that yields a session from it.
See SQL databases.
P2A0506¶
SQL statement
This way of building or executing a statement emits SQL the runtime does not reproduce.
What to do: Build the statement with the supported constructs (see SQL databases) and its own bound values.
See SQL databases.
P2A0507¶
create_all and DDL
metadata.create_all is compiled by running SQLAlchemy at translation time on the declared classes; what SQLAlchemy computes at class creation or in event listeners is not reproduced.
What to do: Declare the tables and columns statically, or create the schema with your migrations (Alembic) and drop create_all from the startup code, or keep the lifespan in Python (--python-side lifespan).
See SQL databases.
P2A0508¶
TypeDecorator
A TypeDecorator is compiled when it wraps a string type with process_bind_param/process_result_value.
What to do: Keep impl a string type and only these two methods (plus cache_ok).
See SQL databases.
P2A0509¶
Table introspection
Model.__table__ and isinstance(col.type, <SQLAlchemy type>) are computed by SQLAlchemy at translation time, on the mapped classes rebuilt from the source.
What to do: Install SQLAlchemy 2.x next to py2axum, and read __table__ from a mapped class of a declarative base.
See SQL databases.
P2A0510¶
Alembic migrations
<binary> migrate replays the SQL alembic's offline mode renders at translation time, with the options env.py and alembic.ini set; an option or a layout it cannot reproduce is refused.
What to do: Keep env.py's context.configure(...) options literal and identical online and offline, keep the revisions under script_location/versions, or keep running alembic upgrade head instead of <binary> migrate.
Project and versions¶
P2A0601¶
Library version outside the tested ranges — whole application
The project locks a version of FastAPI, Starlette, Pydantic, SQLAlchemy or Python that py2axum is not tested against: the binary must behave like the version you run, and behaviour changes between versions.
What to do: Use a version in the tested ranges, or pass --allow-untested-versions after checking the behaviour with a conformance run.
See Versions.
P2A0602¶
Cannot be left to Python
The binary is the only entry point of a hybrid deployment, and this construct cannot be relayed to the Python process.
What to do: Make the construct translate, or route it to Python at your ingress instead of through the binary.
See Hybrid mode.
P2A0603¶
Not available on the project's Python
The construct appeared in a later Python than the one the project runs on (its .python-version, its requires-python, or --python): there, Python raises (AttributeError, TypeError), and the binary follows the project's Python.
What to do: Check the Python py2axum detected (--python X.Y sets it), or write the construct of your Python.
See python-versions.md.
Other¶
P2A0901¶
Internal transpiler error
py2axum failed on a construct it should have either translated or refused.
What to do: This is a py2axum bug: please report it with the file:line and a minimal reproduction. Meanwhile, --python-side '<path>' leaves the route to Python.
See py2axum check.
P2A0999¶
Not supported
The construct is outside the supported subset.
What to do: Rewrite it with a supported construct (see the supported subset). If the construct is essential, leave the route to Python: --python-side auto (or --python-side '<path>') keeps it in a Python process next to the binary.
See Supported subset.