Troubleshooting v0.2¶
Start with make status. It shows which services of a make dev stack operate, and if the
embedded PostgreSQL runs. The Settings page of the web app shows the readiness checks of
the API. curl -s $MAPI_API_URL/readyz shows the same data from a shell.
Port conflicts¶
If a different process uses a port that make dev needs, make dev does not start:
The port can belong to a different make dev (in a different terminal or worktree), a
compose stack, or a program that is not related. Find the process. Then stop it, or move
the platform:
To move the platform, export the addresses in each shell that connects to it. Then start
again. All components (make dev, make seed, make e2e, the CLI, the Python client, the
build of the web app) read the same variables:
export MAPI_API_URL=http://127.0.0.1:18000
export MAPI_GCS_ENDPOINT=http://127.0.0.1:14443
export MAPI_WEB_ORIGIN=http://127.0.0.1:15173
export MAPI_PLOTS_ORIGIN=http://127.0.0.1:15174
make dev
| Port | Variable | Service |
|---|---|---|
| 8000 | MAPI_API_URL |
API |
| 4443 | MAPI_GCS_ENDPOINT |
GCS shim (signed URLs point here) |
| 5173 | MAPI_WEB_ORIGIN |
Web app |
| 5174 | MAPI_PLOTS_ORIGIN |
Plot sandbox |
A state directory is for one stack at a time. To run two stacks at the same time, also give
each stack its own MAPI_DATA_DIR. The Playwright smoke suite (pnpm --filter @mapi/web test)
serves its own build on 5173 and 5174. Thus run it only while make dev is stopped. Docker
Compose publishes the same four ports as make dev, on purpose. Run only one of the two.
The local stack¶
cannot start - fix these first-
The supervisor does a check of each necessary item before it starts a service. In addition to ports, it can show these errors:
module 'mapi_server.__main__' not found: your environment is not current. Runuv sync --all-packages(ormake install).exe 'pnpm' not foundorrun pnpm install first: install pnpm (corepack enable) and the JavaScript dependencies (pnpm install). You can also skip the front end withmake dev WITHOUT=web,plots.
already running (supervisor pid N)- A previous
make devstill runs, possibly in a different terminal. Runmake stop. The process can be gone while its state file stays (for example, afterkill -9). Then the next start finds the dead pid and ignores the file. plots exited unexpectedly with status 143; stopping the stack- A process outside the stack sent
SIGTERMto the service (for example apkill vite). The supervisor never starts services again without a message. It stops all services and stops itself. Start it again. The reconciler recovers the runs that were in progress as a new attempt. postgres | failed to start- Read
.local/pg/log. If the data directory came from a different PostgreSQL major version, or is corrupt, runmake clean-local. This deletes the local database.make stopstops an orphaned server from an earlier crash. migrate exited with status 1- The output of the migration is immediately above this line. Repair the migration, or
reset the database with
make stop && make clean-local. Then runmake devagain. api not ready after 60s- The API process runs, but
GET /healthznever succeeded. Look at theapi |lines. The usual causes are a wrongDATABASE_URL, or a GCS shim that the API cannot connect to. - Validation says the catalog is unavailable
- At the first start against a new environment (and after each change to
uv.lock), the worker puts a sandboxed describe run in the queue to export the catalog:no catalog for sha256:…: queued describe run. This takes some seconds. If it fails, its run page under Runs shows the reason. - The server refuses
MAPI_PROFILE MAPI_PROFILEis also the config-profile variable of the CLI. If you exported a client profile name, unset it in the shell that runsmake dev. The server accepts onlysingle-tenant,multi-tenantordev.- Leftover processes after a crash
- Each service runs in its own process group. You can find it with
ps -o pid,pgid,command. If the supervisor does not respond in 30 s,make stopalso stops the process groups in.local/dev/supervisor.json.
The web app and plots¶
- API unreachable in the header, or the app cannot load data
- The app calls the API at the
VITE_API_BASEthat it started with.make devsets it fromMAPI_API_URL. If you start Vite yourself, also set it. The API must also permit the origin of the app. It permitsMAPI_WEB_ORIGIN, so the two must agree. - Plots stay blank
-
Make sure of these three conditions:
MAPI_WEB_ORIGINandMAPI_PLOTS_ORIGINare different origins.- The plot sandbox runs (
make status). - The sandbox permits the origin of the app (
VITE_APP_ORIGINS, set bymake dev).
The browser console names the blocked origin.
- Uploads fail in the browser
- The browser sends files with PUT directly to
MAPI_GCS_ENDPOINT. The shim must permit the origin of the app (--cors-origin, whichmake devsets fromMAPI_WEB_ORIGIN). The CSP of the app must permit the storage origin (VITE_STORAGE_ORIGINS).
Runs and scoring¶
- A run is
stalled - No progress came for some time. This is a warning, not a failure. The status of the executor decides if the run is alive. A long PyTensor compile on the first fit of a new machine can cause it.
DEV_MODE_ISOLATIONon every run- This is expected on a laptop. The local executor runs the model code as your own user,
without a separate uid or
no_new_privs. Refer to the security model. SIDE_TABLE_COVERAGEwhen scoring- You must give a side table with
score_policy: supplied(in the demo,fx) in the score request (side_tables: {fx: dataset://default/fx_daily@latest}). It must include the scored dates. To skip it, enter the pipeline after the step that uses it (inputs_stage: weekly). MODE_NOT_SUPPORTED,UNSEEN_LEVELS,HORIZON_EXCEEDS_FIT, …- These are typed errors from the static checks. The request asks for an answer that the
model cannot give honestly. The
detailand the JSON pointer of the problem tell what is wrong. Error codes lists the codes. RESOURCE_EXHAUSTED- The run did not have sufficient memory or scratch space. Retry on the run page
suggests the next resource class. Under compose, increase
MAPI_WORKER_MEMORYandMAPI_WORKER_TMPFS. INTEGRITY_FAILUREwhen downloading- The signed manifest of the bundle does not verify. Thus the API does not mint download
links. Locally, this occurs when somebody deleted
.local/keys/. You cannot trust the old model versions after this. Fit again. SCHEMA_INVALID: "the score request has no data"- The request has no data, no scenario dataset and no forecast horizon. The server refuses it before a run starts. Give a dataset, a scenario dataset or a horizon. The Score page shows No new data only for Forecast, or when a scenario dataset gives the values.
SETTINGS_INVALIDbefore the fit starts- The settings of the model break a rule that uses more than one field. The harness reads
the settings before it transforms or splits the data, so this error comes early. The
message tells which settings to change. For example,
sci.storm_localisationrefuses a render of more than 50 million values.
Warnings on a run v0.11¶
A warning does not stop a run. The run page shows each warning in the event timeline.
mapi runs watch RUN and GET /v1/runs/{run_id}/events also give it. These warnings come from
the run tracking, the media, the GPU class and the image collections.
TRACKING_BUDGET- The run logged more than its tracking budget, for example more than 10 000 points in one
series or more than 1000 series. The platform did not keep the points after the budget.
The run gets one warning at the end. The message names the reasons and the series with
the most dropped points. To prevent it, log a curve each k-th step, or use fewer labels.
Tracking budgets gives all the limits.
More than 64 MiB of tracking messages is not a warning. The run then fails with
SANDBOX_VIOLATION. MEDIA_BUDGET- The run logged more than 1000 media items or 256 MiB of media (v0.14). The platform did not
keep the items after the budget. Each attempt gets a maximum of one warning. Log the
images less frequently, for example at each tenth epoch, or log smaller images. Through
the API (
POST /v1/runs/{run_id}/media), the same budget gives429 QUOTA_EXCEEDED. MEDIA_IGNORED,MEDIA_INVALID,MEDIA_UPLOAD_FAILEDandMEDIA_REJECTED- The platform did not keep one media item.
MEDIA_IGNORED: the run has no media policy.MEDIA_INVALID: the item is not a PNG, a JPEG or a valid table, or it is too large.MEDIA_UPLOAD_FAILED: the upload of the supervisor failed.MEDIA_REJECTED: the checks of the server failed. Run protocol: Media tells each check. GPU_UNAVAILABLE-
The run has the resource class
GPU, but the runner sees no NVIDIA device (v0.15). The run continues on the CPU, more slowly. These are the usual causes:- The worker uses the local-process executor. This executor always uses the CPU.
- The docker executor runs with
MAPI_DOCKER_GPUS=false(the default). - The host has no NVIDIA driver or no NVIDIA Container Toolkit.
- The Cloud Run GPU Job has no GPU. This path is not verified (GPU jobs).
After the fix, make sure that the param
dl.backendof the next run isgpu. VIEW_SAMPLE_FAILED- A fit on an image collection could not decode its sample of images (v0.15). The views, the scorecard and the Model Explorer use a sample of a maximum of 500 images. The fit continues without the sample, and the views then show only the manifest. The text of the warning gives the reason, for example an image that the runner cannot read.
CHECKPOINT_SKIPPED- A network did not save one checkpoint, because its
meta.jsonwas larger than 16 MiB (v0.15). The file holds the epoch, the early-stopping state, the training history and the confusion matrices of the epochs. Thus a fit with many epochs or many classes can make it too large. The run continues. If the run stops, the next attempt continues from the last checkpoint that the run saved. CAPABILITY_UNSUPPORTEDat/execution/resource_class- The spec selects the class
GPUfor a model that does not use a GPU. Onlydl.cnn_classifieranddl.finetune_classifieruse the GPU class. SelectS,MorL. The same code with the severityinfotells you that the model can use the GPU class. - An upload of an image collection stopped
- Run the same
mapi datasets upload-imagescommand again with the same--statefile. The client skips the parts that arrived and renews the upload links that expired. The server keeps an upload whose file arrived until 7 days after its PUT URL expired. Refer to Image data: continue an upload.
Workflows and science models v0.9¶
EXPRESSION_ERRORin a branch node- The condition could not be calculated. Usually, it compares a value that is null or not
there, for example the R-hat of a fit with one chain. Wrap the reference in
coalesce(...)orexists(...), or fit two or more chains. PLOT_UNSAFEon a workflow node- The
plotoutput of the node did not pass the plot sanitizer, so the node failed. The server does a check of each plot output when it collects it, and again when it serves it. Look at the recipe and the settings of theplot.rendernode. - The tests of the science plugin skip
- The tests that read the real data of pymc-challenges run only when
MAPI_PYMC_CHALLENGES_DATAgives thedata/directory of a local copy. Refer to Science data. make docs-screenshots-sciencestops at an upload (ENOENT)- The script reads
scotland_lip.nc,heat_plate_e51.nc,lazega_coworkers.nc,unc13_dstorm.nc,primates301.ncandbci_camera_traps.ncfrom.local/science, or from the folder thatMAPI_SCIENCE_DATAgives. Export them first withpython -m mapi_plugin_science.export. - The recipe monitor screenshot shows Reused
make docs-screenshots-scienceran before on the same stack. The server used the earlier results of the recipe again. To capture a run in progress, use a new stack (a newMAPI_DATA_DIR).
Docker and compose¶
error: the Docker daemon is not reachablemake docker-buildandmake compose-upfirst do a check withdocker info. Start Docker Desktop, Colima ordockerd. You can also usemake dev, which needs no Docker.required variable POSTGRES_PASSWORD is missing a value- Copy
.env.exampleto.envand setPOSTGRES_PASSWORD. Compose reads.envfrom the repository root. image check failed: forbidden distribution 'numpy' is installed(server build)- A control-plane dependency now adds a science package. To see the closure, run
uv run python scripts/lock_closure.py "mapi-server[docker]" --lacks numpy. Then find the dependency that addsnumpy. Contracts: 1 brokenin thecontractsstage- Server code imports a forbidden module.
make lint(lint-imports) shows the same failure locally, with the import chain. PyTensor found no C++ compiler(base-bayes / base-forecast build)g++is missing fromMAPI_APT_PACKAGES. The PyMC images also need it at run time.- The
apicontainer is unhealthy -
Run
make compose-logs SERVICE=api. These are the usual causes:migratefailed. Look at its logs.- The
DATABASE_URLpassword does not agree with the database volume. This occurs after you changePOSTGRES_PASSWORD. Then reset withmake compose-down VOLUMES=1. This deletes the data.
no bundle-signing key at /var/lib/mapi/keys/... and MAPI_SIGNING_KEY_CREATE is offapiorworkerstarted beforemigratemade the key, or without thekeysvolume. Do a check withmake compose-logs SERVICE=migrate. Never point the two services at different keys. If you do, the API refuses each bundle that the worker signs, withINTEGRITY_FAILURE.400 Invalid host headerfrom the API, or nginx closes the connection- The stack answers only known host names (a DNS-rebinding guard). You can connect to it
with a name other than
127.0.0.1,localhostorapi. Then add that name toMAPI_ALLOWED_HOSTS(the API) andMAPI_WEB_SERVER_NAMES(the nginx of the web image). mapi-entrypoint: /tmp/mapi-cache is not writable- The container runs with a read-only root filesystem, but without a writable
/tmp. Add--tmpfs /tmp(compose already does this). - Port already allocated on
docker compose up - A
make devstack, or a different process, uses 4443, 8000, 5173 or 5174. Stop it withmake stop. The two stacks use the same ports on purpose, so that the same URLs work with the two stacks. - nginx exits with
host not foundorinvalid number of arguments in "set" MAPI_API_UPSTREAMis empty or malformed. It must be a URL without a path, for examplehttp://api:8000.