nautechsystems/nautilus_trader · error · anyhow::Error
Tag slug '{slug}' not found
Error message
Tag slug '{slug}' not found What it means
resolve_tag_slug fetches all Gamma tags via client.request_tags(), looks up the tag whose slug matches, and errors with "Tag slug '{slug}' not found" when no tag in the returned list has that slug. This happens before any numeric tag ID can be used in Gamma event queries.
Source
Thrown at crates/adapters/polymarket/src/providers.rs:1043
fn parse_gamma_filter_string(scope: &str, key: &str, value: &str) -> anyhow::Result<String> {
if value.trim().is_empty() {
anyhow::bail!("Gamma {scope} filter '{key}' cannot be empty")
}
Ok(value.to_string())
}
/// Resolves a tag slug to a tag ID by querying the Gamma tags endpoint.
pub async fn resolve_tag_slug(
client: &PolymarketGammaHttpClient,
slug: &str,
) -> anyhow::Result<u64> {
let tags = client.request_tags().await?;
let tag_id = tags
.iter()
.find(|t| t.slug.as_deref() == Some(slug))
.map(|t| t.id.as_str())
.ok_or_else(|| anyhow::anyhow!("Tag slug '{slug}' not found"))?;
tag_id
.parse::<u64>()
.map_err(|e| anyhow::anyhow!("Tag slug '{slug}' returned invalid ID '{tag_id}': {e}"))
}
#[async_trait(?Send)]
impl InstrumentProvider for PolymarketInstrumentProvider {
fn store(&self) -> &InstrumentStore {
&self.store
}
fn store_mut(&mut self) -> &mut InstrumentStore {
&mut self.store
}
async fn load_all(&mut self, filters: Option<&HashMap<String, String>>) -> anyhow::Result<()> {
let instruments = self.fetch_bulk_instruments(filters).await?;
self.replace_instruments(instruments);View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the exact slug against Polymarket's Gamma tags endpoint (slugs are matched exactly via t.slug == Some(slug))
- Refresh the tag list — request_tags() is fetched live each call, so a newly added slug works immediately
- Update the config to use the numeric tag ID directly instead of slug resolution where possible
- Check network/proxy responses; a truncated tag list can hide a valid slug
Example fix
// before let tag_id = resolve_tag_slug(&client, "Politics").await?; // after let tag_id = resolve_tag_slug(&client, "politics").await?;
Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: verify slug exists against a cached tag list before querying
fn slug_known(tags: &[GammaTag], slug: &str) -> bool {
tags.iter().any(|t| t.slug.as_deref() == Some(slug))
} Try / catch
// Rust
match resolve_tag_slug(&client, slug).await {
Ok(id) => id,
Err(e) if e.to_string().contains("not found") => {
eprintln!("unknown tag slug '{slug}'; check https://gamma-api.polymarket.com/tags");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Keep slugs lowercase-kebab as returned by the Gamma API; they are matched exactly
- Cache and periodically refresh the tag list to detect renamed slugs
- Prefer numeric tag IDs in long-lived configs to avoid slug churn
When it happens
Trigger: Calling resolve_tag_slug with a slug string that does not exist in Polymarket's Gamma tag list at request time (or an async task within any query path that resolves a tag filter).
Common situations: Typo in slug (case-sensitive match: 'Politics' vs 'politics'), slug renamed/retired by Polymarket, network returning a partial tag list, or stale config referencing an old slug.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Tag slug '{slug}' returned invalid ID '{tag_id}': {e}
- All {total_slugs} slug requests failed
- RTDS task owner was dropped
- params.validate_keyset().map_err(|e| anyhow::anyhow!(e))?;
- Gamma {scope} filter '{key}' must be an unsigned integer: {e
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/73086ae13edac00f.
Report an issue: GitHub.