Typical error:
- EODHD key missing
Fix:
- add
[eodhd].api_keytoprivate/config.toml
Typical cause:
- normalization run before ingestion
Fix:
- ingest first, then normalize
Typical causes:
- required normalized facts are missing
- facts are stale
- market data is missing for valuation metrics
- provider coverage is insufficient for the requested metric
Useful commands:
pyvalue report-fact-freshness --exchange-codes US
pyvalue report-metric-status --exchange-codes US --reasons
pyvalue report-screen-failures --config screeners/quality_reasonable_price_primary.yml --exchange-codes USTypical cause:
- you tried a provider/exchange bulk workflow before refreshing or loading the canonical catalog
Fix:
- run
refresh-supported-exchanges --provider EODHDandrefresh-supported-tickers --provider EODHD --exchange-codes <CODE>
ingest-fundamentals and update-market-data print this when the scope resolves
fine but no ticker in it is eligible. It is not a catalog problem: an unsupported
symbol, an unknown exchange code, an empty scope and (for market data) a secondary
listing each fail earlier with their own error. Only two causes remain, and the
message names the one that applies.
All data is inside the freshness window. The default --max-age-days is 30, so
a symbol refreshed earlier the same day is skipped. Force a re-fetch with a zero
window:
pyvalue ingest-fundamentals --symbols ADBE.US --max-age-days 0
pyvalue update-market-data --symbols ADBE.US --max-age-days 0Before spending quota, check whether the fresh payload is simply waiting to be normalized — a re-fetch of unchanged data will not move any metric:
pyvalue normalize-fundamentals --symbols ADBE.US
pyvalue compute-metrics --symbols ADBE.USEverything stale is serving retry backoff. Previous failures set
next_eligible_at in the future. Retry immediately, or look up when the wait ends:
pyvalue ingest-fundamentals --exchange-codes US --retry-failed-now
pyvalue report-fundamentals-progress --provider EODHDIn that summary, Stored means a fundamentals payload exists in the DB, while
Fresh means the ticker currently counts as complete for the selected mode and
freshness window. --max-age-days 0 is honoured literally, so it reports
everything stored as stale.
Typical causes:
provider_listingwas not refreshed first- old
market_data.as_ofsnapshots are outside the freshness window - some symbols are still inside retry backoff
- today’s EODHD quota is exhausted
Useful commands:
pyvalue update-market-data --provider EODHD --all-supported
pyvalue report-market-data-progress --provider EODHDIn that summary, Stored means a market-data snapshot exists in the DB, while
Fresh means the symbol currently counts as complete for the selected
freshness window.
Market cap is computed on demand as the latest share-count fact x the latest
market_data price (it is no longer a stored column). It is missing when there
is no shares-outstanding fact or no stored price at all.
Typical causes:
- market data not refreshed yet
- no shares-outstanding fact normalized for the symbol
Fix:
pyvalue update-market-data --provider EODHD --exchange-codes USTypical symptom:
- metric refuses to compute even though the symbol exists
Fix:
- refresh fundamentals and/or market data
- re-run normalization
- re-run metric computation
Typical problem:
- the database file stays large after the SEC/Frankfurter cleanup migration (073)
deleted the Frankfurter FX rows and rebuilt
financial_facts
Fix:
VACUUMcannot run inside a migration transaction, so reclaim the freed pages manually once, after upgrading:sqlite3 data/pyvalue.db 'VACUUM;'