koala73/worldmonitor · error · ValidationError

Provide ticker or name

Error message

Provide ticker or name

What it means

getCompanyEnrichment throws ValidationError (field 'ticker') when, after trimming, both req.name and req.ticker are empty. Note the v1 compatibility branch: a request with only domain (deprecated field) returns the safe empty legacyDomainStub and does NOT throw — this error strictly means 'neither ticker nor name'.

Source

Thrown at server/worldmonitor/intelligence/v1/get-company-enrichment.ts:49

  fetchFinnhubCompanyAndEarnings,
} from './_company-shared';

const MAX_RECENT_FILINGS = 15;

export async function getCompanyEnrichment(
  _ctx: ServerContext,
  req: GetCompanyEnrichmentRequest,
): Promise<GetCompanyEnrichmentResponse> {
  const domain = req.domain?.trim().toLowerCase();
  const name = req.name?.trim();
  const ticker = req.ticker?.trim();

  // v1 compatibility: domain attribution remains disabled. Existing callers
  // that still send the deprecated field keep receiving the safe empty stub.
  if (domain && !ticker) return legacyDomainStub(domain, name);

  if (!name && !ticker) {
    throw new ValidationError([{ field: 'ticker', description: 'Provide ticker or name' }]);
  }

  const resolution = await resolveCompany({ ticker, name });
  if (resolution.status !== 'ok') {
    // "not_found" is a real, cacheable answer; "registry_unavailable" is a
    // lookup failure and must not be cached as one.
    return unresolved(ticker, name, resolution.status === 'registry_unavailable');
  }
  const resolved = resolution.company;

  // Finnhub profile + earnings share one gate on cold miss (30/min budget).
  const [submissions, finnhub, news] = await Promise.all([
    fetchSecSubmissions(resolved.cik),
    fetchFinnhubCompanyAndEarnings(resolved.ticker),
    fetchCompanyNewsMentions(resolved.ticker, resolved.name),
  ]);
  const profile = finnhub.profile;
  const earnings = finnhub.earnings;

View on GitHub (pinned to eeab0a219f)

Solutions

  1. Require ticker or name in the client before calling
  2. Prefer ticker when available — resolution by ticker is the most reliable path
  3. Trim inputs client-side and skip the call entirely when both are empty rather than relying on the 400

Example fix

// before
const enriched = await getCompanyEnrichment({ ticker: form.ticker }); // form.ticker may be ''

// after
const ticker = form.ticker?.trim();
const name = form.name?.trim();
if (!ticker && !name) return showInputError('Enter a ticker or company name');
const enriched = await getCompanyEnrichment({ ticker, name });
Defensive patterns

Strategy: validation

Validate before calling

const ticker = req.ticker?.trim();
const name = req.name?.trim();
if (!ticker && !name) {
  throw new ClientError('Provide a ticker or company name');
}

Type guard

function isMissingIdentifierViolation(body: unknown): boolean {
  const v = (body as { violations?: { field?: string; description?: string }[] })?.violations;
  return Array.isArray(v) && v.some((x) => x.field === 'ticker' && x.description === 'Provide ticker or name');
}

Try / catch

try {
  await getCompanyEnrichment({ ticker, name });
} catch (e) {
  if (e instanceof HttpError && e.status === 400 && isMissingIdentifierViolation(e.body)) {
    return promptForCompany();
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling /api/intelligence/v1/get-company-enrichment with an empty body; passing whitespace-only strings for both fields; a form/UI that submits before the user enters a company; passing only the deprecated domain field expecting this error and instead getting the stub.

Common situations: Client-side validation missing so empty searches reach the API; dynamic query building that drops both identifiers after a filter step; scripts iterating a list where some rows have neither ticker nor name.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of koala73/worldmonitor@eeab0a219f (2026-08-21). Data as JSON: /api/errors/948a2e336cbdd132. Report an issue: GitHub.