8.6 KiB
weatherapi Troubleshooting
Use this guide to separate startup, database, template, request-validation, and
no-data problems. For full command and configuration reference, see
docs/cli.md and docs/config.md.
Startup Fails with load config
Symptom: the process exits and logs weatherapi failed: load config: ....
Likely causes:
- the config path is wrong;
- the process working directory is not where
config.ymlis expected; - YAML syntax is invalid;
- required feedapi config fields are missing.
Diagnostic:
ls -l config.yml
python3 -c 'import yaml; yaml.safe_load(open("config.yml"))'
Safe fix: pass the intended file explicitly with -config, or set a non-blank
WEATHERAPI_CONFIG. Fix YAML syntax and compare the file with
examples/config.minimal.yml.
Startup Fails with config.databases requires at least one entry
Symptom: the process exits before opening any database.
Likely cause: databases is missing or empty in the YAML file.
Diagnostic:
rg -n '^databases:' config.yml
Safe fix: add at least one database entry. The first entry is the primary weather data store used for reads.
Startup Fails with open databases
Symptom: the process exits while opening configured database handles.
Likely causes:
- PostgreSQL host or port is unreachable;
- credentials are invalid;
- the database name in
uriis wrong; - TLS/
sslmodesettings do not match the server; - the configured driver is not usable for this deployment.
Diagnostic:
psql 'postgres://USER:PASSWORD@HOST:5432/DBNAME?sslmode=disable' -c 'select 1'
Safe fix: correct uri, username, password, network routing, firewall
rules, or TLS settings. Keep production secrets out of committed config files.
Startup Fails with select primary database
Symptom: databases open, then the process exits selecting the primary database.
Likely cause: feedapi opened a registry that does not contain the first configured database name.
Diagnostic: inspect the first databases item in the active config and verify
that name is present and non-empty.
Safe fix: give the first database entry a stable name and keep it as the
weather database entry.
Startup Fails with build app
Symptom: the process exits after database setup but before serving HTTP.
Likely causes:
- feedapi cannot construct the HTTP app from the config;
- renderer or template setup failed;
- endpoint registration failed.
Diagnostic: read the error text after build app:. If the error mentions
templates, inspect templates.base_dir.
Safe fix: correct the config value mentioned by the error. For template errors,
make the directory readable and ensure the repository's *.txt.tmpl files are
present.
Requests Return 400 invalid_parameter
Symptom: JSON error body includes:
{
"error": {
"code": "invalid_parameter",
"message": "..."
}
}
Likely causes:
- unknown query parameter;
precisionoutside0through2, or not an integer;precisionused on alerts, discussions, weather stories, or outlooks;tzused on observations, current conditions, or alerts;- invalid timezone value;
- both
tzandTZare present with different values.
Diagnostic: compare the request against the route's query parameters in
docs/api.md. Reproduce with curl -i to see the status and body.
Safe fix: remove unsupported parameters or correct values. Use tz=Chicago,
tz=America/Chicago, a supported US abbreviation, or an offset such as TZ=-5
on routes that accept timezone selection.
Requests Return 406 unsupported_format
Symptom: the response status is 406 Not Acceptable and the error code is
unsupported_format.
Likely causes:
formathas a value other thanjson,xml, ortext;- the
Acceptheader cannot be matched to a registered renderer; - the configured default format is unsupported.
Diagnostic:
curl -i 'http://localhost:8080/observations?format=json'
curl -i -H 'Accept: application/json' 'http://localhost:8080/observations'
Safe fix: request format=json, format=xml, or format=text, or set
server.default_format to a supported value.
Text Responses Fail or Do Not Render Expected Text
Symptom: format=text fails, returns an error, or does not contain expected
endpoint text.
Likely causes:
templates.base_dirpoints to the wrong directory;- templates were not copied into the runtime container or deployment directory;
- file permissions prevent reading templates;
- a customized template has invalid syntax.
Diagnostic:
find templates -maxdepth 1 -name '*.txt.tmpl' -print | sort
curl -i 'http://localhost:8080/forecast/hourly?format=text'
Safe fix: restore the repository's templates/ directory or update
templates.base_dir to the mounted template path. In the Docker image, the
default template directory is /weatherapi/templates.
Successful Response Has data: null
Symptom: the response is 200 OK, but JSON contains "data": null.
Likely causes:
- weatherfeeder has not populated the relevant table yet;
- the relevant latest row does not exist after a database restore;
- the service is pointed at an empty or wrong database;
- current conditions have no observations in the implemented 30-minute window.
Diagnostic:
curl -s 'http://localhost:8080/observations?format=json'
curl -s 'http://localhost:8080/conditions/current?format=json'
Safe fix: verify weatherfeeder is running and writing to the same database that
weatherapi uses as its first configured database. For current conditions,
wait for recent observations or inspect weatherfeeder ingestion.
For convective outlooks, also verify that weatherfeeder has applied its
weather.outlook.v2 table shape and is writing outlook_runs, outlooks, and
outlook_discussions.
Forecast Day Routes Return Empty periods
Symptom: /forecast/hourly/today, /forecast/hourly/tomorrow,
/forecast/narrative/today, or /forecast/narrative/tomorrow returns a
forecast object with an empty periods array.
Likely causes:
- no period
startTimefalls on that calendar day in the selected timezone; - the request omitted
tz, so UTC day boundaries were used; - the stored forecast is stale.
Diagnostic:
curl -s 'http://localhost:8080/forecast/hourly/today?tz=America/Chicago'
curl -s 'http://localhost:8080/forecast/hourly?tz=America/Chicago'
Safe fix: provide the intended tz value and verify the unfiltered forecast
contains periods for the expected local date.
Timezone Errors
Symptom: requests with tz or TZ return 400 invalid_parameter.
Likely causes:
- the timezone is not an IANA location, supported US abbreviation, supported alias, or valid UTC offset;
- an offset is outside
-14:00through+14:00; - both
tzandTZare present but do not match case-insensitively.
Diagnostic:
curl -i 'http://localhost:8080/forecast/hourly?tz=not-a-timezone'
curl -i 'http://localhost:8080/forecast/hourly?tz=CDT&TZ=EST'
Safe fix: use one timezone parameter. Known-good examples include
tz=America/Chicago, tz=Chicago, tz=CDT, and TZ=-5.
Precision Errors
Symptom: requests with precision return 400 invalid_parameter.
Likely causes:
- value is not an integer;
- value is less than
0or greater than2; - route does not accept
precision.
Diagnostic:
curl -i 'http://localhost:8080/conditions/current?precision=3'
curl -i 'http://localhost:8080/alerts/active?precision=1'
Safe fix: use precision=0, precision=1, or precision=2 only on
observations, current conditions, and forecast routes.
Missing or Stale Weather Data
Symptom: responses are successful but older than expected, or endpoint families are empty.
Likely causes:
- weatherfeeder is stopped or failing;
- weatherfeeder writes to a different database than
weatherapireads; - a restore or deployment changed database credentials;
- upstream provider ingestion is delayed outside
weatherapi.
Diagnostic: inspect weatherfeeder logs and query the configured Postgres database directly for recent rows in the relevant weatherfeeder tables.
Safe fix: repair weatherfeeder ingestion or database routing. Restart
weatherapi only when config or database connectivity changed.
Related Docs
docs/api.md: endpoint contract, query parameters, errorsdocs/config.md: YAML fields and examplesdocs/operations.md: runtime and recovery boundariesdocs/integrations/feedapi.md: config, rendering, and error-contract boundariesdocs/integrations/weatherfeeder-postgres.md: table and freshness assumptions