Skip to content

TS SDK Metaculus sends auth in credentials.apiKey but core factory reads credentials.apiToken #882

Closed as duplicate

Description

@realfishsam

Gap

The core exchange factory uses credentials.apiToken (not credentials.apiKey) to authenticate Metaculus requests. The TS SDK Metaculus class accepts only ExchangeOptions, which provides no apiToken field. When the TS SDK sends credentials, it puts the token in credentials.apiKey. The factory ignores credentials.apiKey for Metaculus and only reads credentials.apiToken, so the token is silently discarded and auth falls back to the environment variable only.

Evidence

Core factory (core/src/server/exchange-factory.ts:100–104):

case "metaculus":
  return new MetaculusExchange({
    apiToken: credentials?.apiToken || process.env.METACULUS_API_TOKEN,
    // No reference to credentials.apiKey
  });

TS SDK ExchangeOptions (sdks/typescript/pmxt/client.ts:194–239):

export interface ExchangeOptions {
    apiKey?: string;   // <-- user passes their Metaculus token here
    // No apiToken field
}

TS SDK getCredentials() (sdks/typescript/pmxt/client.ts:359–368):

return {
    apiKey: this.apiKey,   // <-- becomes credentials.apiKey on the server
    // credentials.apiToken is never populated
};

Python SDK (sdks/python/pmxt/client.py:291,324,500–501):

def __init__(self, ..., api_token: Optional[str] = None, ...):
    self.api_token = api_token

def _get_credentials_dict(self):
    ...
    if self.api_token:
        creds["apiToken"] = self.api_token  # correctly maps to credentials.apiToken

Python SDK Metaculus (sdks/python/pmxt/_exchanges.py:314–339):

class Metaculus(Exchange):
    def __init__(self, api_token: Optional[str] = None, ...):
        super().__init__(exchange_name="metaculus", api_token=api_token, ...)

Impact

A TS SDK user doing:

const metaculus = new Metaculus({ apiKey: 'my-metaculus-token' });

…sends credentials.apiKey = 'my-metaculus-token' to the server. The factory reads credentials.apiToken, finds it undefined, and falls back to process.env.METACULUS_API_TOKEN. If that env var is not set, the exchange initializes unauthenticated even though the user explicitly provided a token.

The fix requires adding an apiToken field to ExchangeOptions (or a MetaculusOptions subtype) and including it in getCredentials().

Activity

  1. realfishsam commented on Jun 6, 2026

    @realfishsam
    ContributorAuthor

    Closing as duplicate of #465. Same underlying finding: Metaculus credential field is named api_token/apiToken in Python and core but apiKey in the TS SDK, causing silent auth failure. The additional context from this issue (exact core factory code at exchange-factory.ts:100–104 and the getCredentials() implementation) has been copied as a comment on #465.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions