koala73/worldmonitor · warning · ValidationError

Unsupported FRED series ID

Error message

Unsupported FRED series ID

What it means

getFredSeries only serves an allowlist of FRED series IDs (ALLOWED_FRED_SERIES). If the normalized req.seriesId is not in that set, the handler marks the response no-store and throws a ValidationError on field 'series_id' with 'Unsupported FRED series ID'. This prevents arbitrary upstream FRED fetches.

Solutions

  1. Pick a seriesId from the supported allowlist (check ALLOWED_FRED_SERIES in server/worldmonitor/economic/v1/get-fred-series.ts)
  2. Trim and uppercase your seriesId before calling to match normalization
  3. If you need a new series, add it to ALLOWED_FRED_SERIES in the server code rather than working around it

Example fix

// before
await getFredSeries(ctx, { seriesId: 'CIVPART2' });
// after
await getFredSeries(ctx, { seriesId: 'CIVPART' }); // ID present in ALLOWED_FRED_SERIES
Defensive patterns

Strategy: validation

Validate before calling

const id = (seriesId ?? '').trim().toUpperCase();
if (!ALLOWED_FRED_SERIES.has(id)) throw new Error(`seriesId ${id} is not in the supported allowlist`);

Try / catch

try {
  return await getFredSeries(ctx, { seriesId });
} catch (e) {
  if (e instanceof ValidationError && e.issues.some(i => i.field === 'series_id')) {
    return { error: 'unsupported series', supported: [...ALLOWED_FRED_SERIES] };
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling get-fred-series with seriesId 'GDP2', 'MY_CUSTOM_SERIES', a lowercase-but-unknown id, or any real FRED series not yet added to the allowlist.

Common situations: Assuming any valid FRED mnemonic works; typos in the series ID; a series removed from or never added to the allowlist after a FRED catalog change; user-entered series in a config UI.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15). Data as JSON: /api/errors/f477a44188b34988. Report an issue: GitHub.

Appendix: source

Thrown at server/worldmonitor/economic/v1/get-fred-series.ts:24

import type {
  ServerContext,
  GetFredSeriesRequest,
  GetFredSeriesResponse,
} from '../../../../src/generated/server/worldmonitor/economic/v1/service_server';
import { ValidationError } from '../../../../src/generated/server/worldmonitor/economic/v1/service_server';

import { getCachedJson } from '../../../_shared/redis';
import { markNoStoreFallbackResponse, setResponseHeader } from '../../../_shared/response-headers';
import { ALLOWED_FRED_SERIES, applyFredObservationLimit, fredSeedKey, normalizeFredLimit } from './_fred-shared';

export async function getFredSeries(
  ctx: ServerContext,
  req: GetFredSeriesRequest,
): Promise<GetFredSeriesResponse> {
  const seriesId = (req.seriesId ?? '').trim().toUpperCase();
  if (!ALLOWED_FRED_SERIES.has(seriesId)) {
    setResponseHeader(ctx.request, 'Cache-Control', 'no-store');
    throw new ValidationError([{ field: 'series_id', description: 'Unsupported FRED series ID' }]);
  }
  try {
    const seedKey = fredSeedKey(seriesId);
    const result = await getCachedJson(seedKey, true) as GetFredSeriesResponse | null;
    if (!result?.series) return markNoStoreFallbackResponse(ctx.request, { series: undefined });
    const limit = normalizeFredLimit(req.limit);
    return { series: applyFredObservationLimit(result.series, limit) };
  } catch {
    return markNoStoreFallbackResponse(ctx.request, { series: undefined });
  }
}

View on GitHub (pinned to 7d06c8633d)