discordjs/discord.js · error · Error
A client id must be provided to login
Error message
A client id must be provided to login
What it means
The RPC client's login() throws this plain Error when RPCLoginOptions.clientId is missing/empty, before any connection is attempted. The RPC (rich presence) transport needs the OAuth application's client id to authenticate the socket, so login() validates it upfront at client.ts:229.
Source
Thrown at packages/rpc/src/client.ts:229
return promise;
}
/**
* Performs authentication flow. Automatically calls Client#connect if needed.
*
* @example
* logging in with a client id and secret
* ```ts
* client.login({ clientId: '1234567', clientSecret: 'abcdef123' });
* ```
*/
public async login(
{ clientId, clientSecret, accessToken }: RPCLoginOptions,
options?: RequestOptions,
): Promise<RPCClient> {
if (!clientId) {
throw new Error('A client id must be provided to login');
}
this.clientId = clientId;
await this.connect(options);
if (!this.options.scopes) {
this.emit(Events.ApplicationReady);
return this;
}
if (accessToken) {
return this.authenticate(accessToken, options);
}
if (!clientSecret) {
throw new Error('A client secret must be provided for authorization if scopes are included');
}View on GitHub (pinned to a81ed8a306)
Solutions
- Pass clientId explicitly: client.login({ clientId: 'your-application-id' }) using the application's ID from the Developer Portal.
- If loading from env, check it exists before login: if (!process.env.DISCORD_CLIENT_ID) throw ...; and ensure dotenv.config() ran.
- Verify the option key is exactly clientId (RPCLoginOptions), not client_id or applicationId.
- If you already have an accessToken from a prior OAuth flow, you still must supply clientId alongside it.
Example fix
// before
await client.login({ clientSecret: process.env.CLIENT_SECRET });
// after
if (!process.env.DISCORD_CLIENT_ID) throw new Error('DISCORD_CLIENT_ID is not set');
await client.login({
clientId: process.env.DISCORD_CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
}); Defensive patterns
Strategy: validation
Validate before calling
function requireClientId(clientId?: string): string {
if (typeof clientId !== 'string' || clientId.length === 0) {
throw new Error('clientId is required for RPC login');
}
return clientId;
}
// usage
const clientId = requireClientId(process.env.DISCORD_CLIENT_ID); Type guard
function hasClientId(o: Partial<RPCLoginOptions>): o is RPCLoginOptions & { clientId: string } {
return typeof o.clientId === 'string' && o.clientId.length > 0;
} Try / catch
try {
await client.login(options);
} catch (e) {
if (e instanceof Error && e.message === 'A client id must be provided to login') {
console.error('Set clientId in RPCLoginOptions (from the Developer Portal application id)');
} else throw e;
} Prevention
- Store the application client id in an env var and assert it at startup before login().
- Load dotenv before reading env vars in scripts.
- Use the exact option key clientId on RPCLoginOptions.
- Keep client id and client secret in one config object so one is not forgotten.
- Add a config schema check (zod/ajv) for login options in application bootstrap.
When it happens
Trigger: Calling client.login({}) or client.login({ clientSecret, accessToken }) without clientId; passing clientId from an unset environment variable (process.env.DISCORD_CLIENT_ID === undefined); typo in the option key (client_id or applicationId instead of clientId).
Common situations: Rich-presence scripts run without a .env file loaded (dotenv not required first); copying example code that reads env vars that were never set; hardcoding secret but forgetting the public client id; migrating from another RPC library whose option name differs.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Cannot set an interval greater than 4 hours
- A client secret must be provided for authorization if scopes
- Package ${packageName} not releaseable
- The --tag option can only be used with --dev
- ClientMissingIntents
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/448cb2b79c2ffd68.
Report an issue: GitHub.