n8n-io/n8n · warning · BadRequestError
Invalid Credential type: "${credentialType}"
Error message
Invalid Credential type: "${credentialType}" What it means
The credential-translation endpoint validates the requested credential type against registered credential types via credentialTypes.recognizes(credentialType). An unrecognized type is rejected with 400 BadRequestError, echoing the supplied value.
Source
Thrown at packages/cli/src/controllers/translation.controller.ts:31
export const NODE_HEADERS_PATH = safeJoinPath(NODES_BASE_DIR, 'dist/nodes/headers');
export declare namespace TranslationRequest {
export type Credential = Request<{}, {}, {}, { credentialType: string }>;
}
@RestController('/')
export class TranslationController {
constructor(
private readonly credentialTypes: CredentialTypes,
private readonly globalConfig: GlobalConfig,
) {}
@Get('/credential-translation')
async getCredentialTranslation(req: TranslationRequest.Credential) {
const { credentialType } = req.query;
if (!this.credentialTypes.recognizes(credentialType))
throw new BadRequestError(`Invalid Credential type: "${credentialType}"`);
const { defaultLocale } = this.globalConfig;
const translationPath = safeJoinPath(
CREDENTIAL_TRANSLATIONS_DIR,
defaultLocale,
`${credentialType}.json`,
);
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return require(translationPath);
} catch (error) {
return null;
}
}
@Get('/node-translation-headers')
async getNodeTranslationHeaders() {View on GitHub (pinned to 5ac6606e81)
Solutions
- Verify the credential type is installed and loaded (check the node/credential registry).
- Correct the query param spelling/casing to match the registered type exactly.
- If a custom credential, ensure the node package is installed and registered before the request.
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the type is registered before requesting its translation.
async function isKnownCredentialType(listCredentialTypes, type) {
const known = await listCredentialTypes();
return known.includes(type);
} Type guard
function isRegisteredCredentialType(type, knownTypes) {
return typeof type === 'string' && Array.isArray(knownTypes) && knownTypes.includes(type);
} Try / catch
try {
await api.get('/credential-translation', { params: { credentialType } });
} catch (e) {
if (e.status === 400 && /Invalid Credential type/.test(e.message)) {
// fix the type name/casing or ensure the credential is loaded, then retry
} else { throw e; }
} Prevention
- Drive the type from the loaded credential registry, not a hardcoded string.
- Validate query param casing matches the registered type exactly.
When it happens
Trigger: GET /credential-translation?credentialType=Foo where 'Foo' is not a registered/loaded credential type.
Common situations: Typo in the query param; a community/custom node providing the credential is not installed or failed to load; the credential type was renamed across versions; calling before nodes-base finished loading.
Related errors
- NODE_NOT_FOUND
- SAME_NAME
- NAME_CONFLICT
- Azure AI Search endpoint is missing or invalid
- Expected Supabase credentials host to be a string
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/ab366d4996380086.
Report an issue: GitHub.