Troubleshooting

Common issues encountered while configuring, running, or contributing to the WWF Traffic Workflow, and how to resolve them. If your issue isn't listed here, open an issue on GitHub.

Connecting to the Traffic Portal

Provide either `token` or both `username` and `password`.

connect_to_portal requires either an Access Token or both Email and Password — leaving all three blank raises this error immediately, before any request is sent to the portal.

Connection fails with a 401/403 error

This is an authentication failure — either the email/password combination is wrong, or the supplied Access Token is invalid or expired. Unlike a browser login, there's no login form to silently re-show; the run fails immediately with the portal's own error message.

The run pauses partway through the download step, then continues on its own

This is expected: the client automatically detects when the portal rate-limits a request (HTTP 429), waits (honoring the portal's Retry-After header when present, otherwise backing off), and retries automatically before giving up. Persistent rate-limiting after several retries will surface as a rate-limit error — if that happens consistently, space out repeated runs against the same account.

Downloading & Merging Traffic Portal Exports

KeyError or column-not-found error after the download step

map_columns runs with raise_if_not_found: true, so the run fails immediately if any of the 23 expected columns (see the Requirements list) is missing from the merged data. This most commonly means Include Species or Include Locations under Download Traffic Portal Incidents was turned off — both are required, alongside the always-included incident export, for the merge to have every expected column.

Category of Incident, Country of Incident, or Date of Incident has unexpected/wrong values

These three columns exist in more than one of the three downloaded exports. After the merge, only the _x-suffixed variant — the value from whichever export was downloaded first — is kept. The incident/case export is always requested first, so its values win.

No incidents at all, even for a time range I know has data

Check the Countries field under Download Traffic Portal Incidents — it defaults to Rwanda, Uganda, and Congo, Democratic Republic of The, so incidents outside those countries are excluded from the search itself, before they ever reach the GVL boundary/country filters described below. If you see [wtp] no matching incidents; skipping export in the run log, the search genuinely found nothing for your time range/species/countries combination — the download step returns no files and the rest of the pipeline has nothing to process.

Merge produces far fewer (or far more) rows than expected

load_and_merge_csvs merges the downloaded exports sequentially on Report ID. If you also merge in an extra local CSV via Load Extra Data, mismatched Report ID values between it and the portal data (extra whitespace, different casing, leading zeros dropped by a spreadsheet tool) will fail to match and effectively disappear from the merged result.

GVL Filtering

An incident I expected to see is missing from every output

Two independent filters must both pass: (1) the incident's point geometry must fall within the GVL 30 km buffer polygon, and (2) its country_of_incident value must be exactly one of Rwanda, Uganda, or Congo, Democratic Republic of The. An incident can be geometrically inside the buffer and still be dropped if its country text doesn't match one of these three strings exactly (e.g. “DRC” or “Democratic Republic of Congo” would not match).

No incidents appear on either map even though the summary table has rows

Check Latitude/Longitude in the trade-route/location export — if these are missing or non-numeric, df_to_point_gdf cannot build point geometry and the spatial join against the GVL boundary will drop the record before it reaches the maps.

Species & Category Labels

A species or incident category shows its raw/original text instead of a simplified label

Both mappings use keep_unmapped: true, so a scientific name or incident-category string not covered by the mapping table (see the Technical Guide, §3.6) passes through unchanged rather than being dropped or erroring. This is expected for taxa or categories outside the current mapping list.

Reports & Dashboard

Two files share the same incidents_by_species (or incidents_by_category) suffix — which one is the map and which is the chart?

This is a known naming quirk: the Incidents Map is persisted with suffix incidents_by_category (matching the incidents-by-category bar chart's suffix), and the Species Map with suffix incidents_by_species (matching the incidents-by-species bar chart's suffix). Each file is additionally prefixed with a content hash, so nothing is overwritten — but you'll need to open the file or check the dashboard widget title to tell map and chart apart.

Conviction Rate on the dashboard doesn't match a per-year rate I calculated manually from the CSV

The dashboard's Conviction Rate widget is an all-time ratio (total imprisoned ÷ total arrested across the whole time range), not a per-year figure. A separate per-year conviction rate is computed internally (add_conviction_rate) but is never persisted or displayed — this is dead code in the current spec.yaml.

No outputs written / can't find results

All outputs are written to the directory specified by the ECOSCOPE_WORKFLOWS_RESULTS environment variable. Confirm it's set and points to a directory the workflow process can write to.

Contributing & CI

These apply if you're modifying the workflow itself (spec.yaml or the generated ecoscope-workflows-wwf-traffic-workflow/ directory) and opening a pull request.

test-cases.yaml not found

This repository currently has no test-cases.yaml file, and CI's test-case validation step requires one with at least one entry. Add a test-cases.yaml with a params block (following the format used in sibling workflows) before CI will pass.

Generated files differ from committed files in ecoscope-workflows-wwf-traffic-workflow

The generated workflow directory is out of sync with spec.yaml. Run the recompile script locally and commit the result:

pixi run --manifest-path pixi.toml --locked bash -c "./dev/recompile.sh --update"

Found wildcard version (*) in requirements or Found local file channel (file://) in requirements

In spec.yaml, every dependency under requirements must pin an exact version (or version range) and use a remote conda channel — wildcard versions and local file:// channels are only valid for local development, not for CI using published packages.

VERSION.yaml (...) must be greater than main branch (...)

Bump MAJ/MIN/PATCH in ecoscope-workflows-wwf-traffic-workflow/VERSION.yaml so it's strictly greater than the version on main before opening or updating a PR.

Workflow tests fail in CI but pass locally (or vice versa)

test.yml runs test cases against all of ubuntu-latest, macos-latest, and windows-latest. Since this workflow has no EarthRanger dependency, a CI-only failure is more likely to come from the GVL boundary Dropbox download being unreachable, or from the Wildlife Trade Portal itself being temporarily unreachable or rate-limiting the CI runner.