Skip to main content

Monitoring and debugging Flights

Preview
This feature is in preview and is subject to change.

A Flight that runs unattended needs to be observable. This page covers reading runs, reading logs, common failure patterns, and inspecting historical versions when something went wrong on a past run.

Listing runs

Every Flight tracks its run history. Get the recent runs newest-first:

Ask your AI agent:

"Show me the last 10 runs of the heartbeat Flight."

The agent calls list_flight_runs and formats the result.

Reading logs

Logs are the combined stdout and stderr captured during the run. Use them to verify what your Flight printed and to read tracebacks from failed runs.

get_flight_run_logs(flight_id, run_number)

The response includes the run record and log content. When the log is large, the response is the tail; pass max_bytes to control the size cap.

Common failure patterns

Most failed runs fall into a handful of categories. Read the log first, then match the symptom:

Symptom in the logLikely causeFix
ModuleNotFoundError: No module named '<x>'The package isn't in requirements.txt, or the name is misspelled.Add or correct the entry, then update_flight (produces a fresh version).
InvalidInputException: ... CreateShortLivedToken: Unable to resolve userThe Flight was created with an explicit access_token_name that doesn't exist in the environment the Flight is talking to (often a staging vs prod confusion).Verify the token exists with SELECT token_name FROM md_access_tokens() in the MotherDuck UI SQL editor or DuckDB CLI against the same MotherDuck environment.
duckdb.duckdb.IOException: ... Could not find file or Catalog Error: ... does not existThe Flight uses a database it can't reach with the permissions of the identity it runs as, or the data isn't there.Check the privileges of the user or service account the Flight runs as and whether the source files or shares are attached.
Schedule didn't fireThe Flight has no schedule_cron, or the cron expression is in local time when it should be UTC.Check schedule_cron on MD_LIST_FLIGHTS() and convert the intended time to UTC.
Run uses "old" source after an updateThe run started before the update landed and locked to the previous version.Trigger a fresh run; subsequent runs use the latest version.
pip install errors during startupA requirement can't be resolved (typo, yanked version, missing platform wheel).Check PyPI for the exact package and version, and pin to a version with a Linux wheel.
Run cancelled unexpectedlySomeone clicked Cancel in the UI, or the run hit a timeout.Check the trigger and the duration in the run record.
Run fails near the end of a large build with little or no log; the run record shows a non-zero exit_codeThe runtime hit its memory ceiling and was OOM-killed.Lower peak memory: push heavy compute into SQL, process in bounded chunks, and lower dbt --threads. See runtime limits.

If the failure doesn't match any of these, capture the full traceback from the log and the run record before re-running — that's the information support needs.

Inspecting a specific version

If a past run misbehaved and the current Flight source has moved on, you can still see exactly what that run executed.

List versions:

SELECT version, created_at, source_code
FROM MD_LIST_FLIGHT_VERSIONS(flight_id := '<flight_id>')
ORDER BY version DESC;

Or get a single version with full content:

SELECT *
FROM MD_GET_FLIGHT_VERSION(flight_id := '<flight_id>', version_number := <n>);

Through the MCP server, the equivalent calls are list_flight_versions and get_flight with a version argument.

The flight_version column on MD_LIST_FLIGHT_RUNS tells you which version a given run used. Combine the two to read the exact source and requirements that produced a failed run.

When the log isn't enough

Some failures don't surface much stdout/stderr — for example, an OOM kill or a process the runtime terminated. Start with the run record from MD_LIST_FLIGHT_RUNS: status, flight_version, the started_at/ended_at timings, the config the run used, and the process exit_code:

  • RUN_STATUS_FAILED with no useful log usually means the process failed before it could print the traceback, or the runtime terminated it.
  • RUN_STATUS_FAILED with a short log ending during dependency installation usually points to package resolution, platform wheels, or startup limits.
  • RUN_STATUS_CANCELLED with a manual trigger is someone clicking the button or calling the cancel API.

Match the pattern, add observability to your main() (a log line at each milestone, a print of memory usage if you suspect OOM), and re-run.

Getting help

For issues that aren't in the failure table above, gather:

  • The Flight's name or ID.
  • The failing run number.
  • The full log content (use max_bytes set high enough to capture the whole thing).
  • The flight_version the run used (from MD_LIST_FLIGHT_RUNS).

Then reach out through your usual MotherDuck support channel.