decolua/9router · error
clientId is required for external_idp refresh
Error message
clientId is required for external_idp refresh
What it means
When building refresh parameters, the clientId must be present in providerSpecificData (as clientId or client_id). It is sent as the client_id field of the Microsoft token refresh POST. This guard fires when the stored provider-specific metadata lacks the client id — usually meaning the credential was created by a path that skipped normalization.
Source
Thrown at src/lib/oauth/kiroExternalIdp.js:136
providerSpecificData: {
profileArn,
region,
authMethod: "external_idp",
provider: "CLIProxyAPI",
clientId,
tokenEndpoint,
scope,
},
};
}
export function buildExternalIdpRefreshParams(refreshToken, providerSpecificData = {}) {
const clientId = normalizeString(providerSpecificData.clientId || providerSpecificData.client_id);
const tokenEndpoint = validateMicrosoftTokenEndpoint(providerSpecificData.tokenEndpoint || providerSpecificData.token_endpoint);
const scope = normalizeScope(providerSpecificData.scope || providerSpecificData.scopes);
if (!refreshToken) throw new Error("refresh token is required");
if (!clientId) throw new Error("clientId is required for external_idp refresh");
if (!scope) throw new Error("scope is required for external_idp refresh");
return {
tokenEndpoint,
body: new URLSearchParams({
grant_type: "refresh_token",
client_id: clientId,
refresh_token: refreshToken,
scope,
}),
providerSpecificData: {
...providerSpecificData,
authMethod: "external_idp",
clientId,
tokenEndpoint,
scope,
},
};View on GitHub (pinned to 90b52e06ff)
Solutions
- Ensure accounts are created through normalizeKiroExternalIdpAuth so providerSpecificData.clientId is populated
- Re-import the account with the complete CLIProxyAPI auth JSON including client_id
- If migrating, backfill providerSpecificData.clientId from the original auth file before refreshing
- Check key names: only clientId and client_id are read from providerSpecificData
Example fix
// before
buildExternalIdpRefreshParams(rt, { token_endpoint: url, scopes: 'openid' })
// after
buildExternalIdpRefreshParams(rt, { token_endpoint: url, scopes: 'openid', client_id: '04b07795-8ddb-461a-bbee-02f9e1bf7b46' }) Defensive patterns
Strategy: validation
Validate before calling
const psd = account.providerSpecificData ?? {};
const clientId = psd.clientId ?? psd.client_id;
if (typeof clientId !== 'string' || !clientId.trim()) {
throw new Error('providerSpecificData missing clientId; re-import the account');
} Type guard
function hasRefreshClientId(psd) {
return typeof psd === 'object' && psd !== null &&
['clientId', 'client_id'].some(k => typeof psd[k] === 'string' && psd[k].trim() !== '');
} Try / catch
try {
const params = buildExternalIdpRefreshParams(rt, account.providerSpecificData);
} catch (e) {
if (e.message === 'clientId is required for external_idp refresh') {
console.error('Account metadata incomplete; re-import with full CLIProxyAPI auth JSON');
}
throw e;
} Prevention
- Create providerSpecificData only through normalizeKiroExternalIdpAuth so clientId/tokenEndpoint/scope are all set
- Backfill clientId when migrating accounts from older storage schemas
- Use exactly clientId or client_id as the metadata key — variants like clientID are ignored
- Add a startup integrity check that every external_idp account has clientId, tokenEndpoint, and scope
When it happens
Trigger: buildExternalIdpRefreshParams(refreshToken, {}) or with metadata missing clientId/client_id, e.g. data constructed manually, migrated from an older schema, or with keys named 'clientID'/'application_id' that aren't recognized.
Common situations: Accounts migrated from an older storage layout that stored client metadata elsewhere; hand-crafted providerSpecificData in tests or scripts; a partial object spread that dropped clientId; importing via a path that never ran normalizeKiroExternalIdpAuth.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- client_id is required
- scope is required for external_idp refresh
- Zed callback must include user_id and access_token
- Failed to refresh credentials. Please re-authorize the conne
- access_token is required
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/4bdc462df3daa15b.
Report an issue: GitHub.