zfin/docs/explanation/faq-troubleshooting.md
Emil Lerch 74fc219afd
All checks were successful
Generic zig build / build (push) Successful in 5m48s
Generic zig build / publish-macos (push) Successful in 11s
Generic zig build / deploy (push) Successful in 23s
add docs/guides
2026-06-22 14:53:53 -07:00

4.4 KiB

FAQ and troubleshooting

Common questions and the quick fixes. If something here doesn't cover your case, the relevant reference page usually does.

Setup and keys

"Error: No API key set." zfin needs at least TIINGO_API_KEY to fetch price history. Set it in your environment or .env. See Getting started and environment variables.

Total-return columns are blank or match price-only. Total return needs dividend data from Polygon -- set POLYGON_API_KEY. Without it you get price-only returns. See Returns and performance.

ETF profiles or enrich don't work. SEC EDGAR requires a contact email. Set ZFIN_USER_EMAIL to your address (it's not a key). See zfin enrich.

Missing or odd data

A holding shows up as "Unclassified." It has no metadata.srf entry, or the entry's symbol:: doesn't match the lot's symbol::/ticker::. Add a classification line; see Classify your holdings.

An account shows as "Unknown" in the tax-type breakdown. It's missing from accounts.srf, or the account:: name doesn't match the lot's account:: exactly (names must match character-for-character). See Map your accounts.

A stock or ETF shows "no earnings data." ETFs, mutual funds, CUSIPs, and some dual-class shares (e.g. BRK.B) return no earnings on FMP's free tier. This is an expected limitation, not a bug. See Why multiple data providers.

A mutual fund price looks like yesterday's. Mutual-fund NAVs publish after market close (after midnight ET for some funds), so intraday you'll see the prior NAV until the new one posts.

quote says the symbol is unavailable, but perf works. You're probably in offline mode (--refresh-data=never). Quotes are never cached, so offline there's nothing to serve; candle-based commands still work from cache. See Caching and data freshness.

A row is shown in warning (yellow) color. That's a manual-priced lot -- its price came from the lot's price:: field, not a live feed, so it may be stale. Update price:: / price_date::, or run zfin audit to find stale ones.

Behavior

A run printed "(using cached data)." zfin served fresh-enough cached data instead of hitting the network -- normal and fast. Force a refetch with --refresh-data=force. See Offline use and refreshing data.

A refresh seems slow / pauses. The rate limiter is spacing requests to stay under a provider's free-tier limit (e.g. Polygon 5/min). It blocks rather than failing. See rate limiting.

zfin can't find my portfolio. It looks in ZFIN_HOME if set, otherwise the current directory. Set ZFIN_HOME to your data directory, or cd into it. accounts.srf and metadata.srf load from the same directory as the resolved portfolio.srf. See core concepts.

CLI and TUI show different totals. They shouldn't -- both union-merge every portfolio*.srf in ZFIN_HOME. If they differ, check whether you passed a narrowing -p pattern to one but not the other, or whether one is using a stale cache vs. live prices.

contributions reports "No changes detected." It diffs git revisions of your portfolio. With a clean tree it compares HEAD~1..HEAD; if your last commit didn't change holdings, there's nothing to show. Use --since to widen the window. See Track contributions.

Data hygiene

Lots of "overdue for update" accounts in audit. The default cadence is weekly and nags until satisfied. Set update_cadence::monthly|quarterly|none per account in accounts.srf.

A transfer between my accounts inflated my contributions. Declare it in transaction_log.srf so it isn't counted as new money. See Track contributions.

See also