n8n-io/n8n · error · UserError
File does not seem to contain credentials. Make sure the cre
Error message
File does not seem to contain credentials. Make sure the credentials are contained in an array.
What it means
Thrown by readCredentials when not using `--separate`: the JSON file parsed but is not an array. The single-file credential import format requires an array of credential objects, even for a single credential.
Source
Thrown at packages/cli/src/commands/import/credentials.ts:365
let credentials: Array<Partial<CredentialsEntity>>;
if (separate) {
const files = await glob('*.json', {
cwd: inputPath,
absolute: true,
});
credentials = files.map((file) =>
jsonParse<Partial<CredentialsEntity>>(fs.readFileSync(file, { encoding: 'utf8' })),
);
} else {
const credentialsUnchecked = jsonParse<Array<Partial<CredentialsEntity>>>(
fs.readFileSync(inputPath, { encoding: 'utf8' }),
);
if (!Array.isArray(credentialsUnchecked)) {
throw new UserError(
'File does not seem to contain credentials. Make sure the credentials are contained in an array.',
);
}
credentials = credentialsUnchecked;
}
const knownProperties = new Set(credentials.flatMap((credential) => Object.keys(credential)));
this.warnOnUnknownProperties(include, knownProperties, '--include');
this.warnOnUnknownProperties(exclude, knownProperties, '--exclude');
return await Promise.all(
credentials.map(async (credential) => {
const filteredCredential = this.filterCredentialProperties(credential, include, exclude);
if (isCredentialData(filteredCredential.data)) {
// plain data / decrypted input. Should be encrypted first.
filteredCredential.data = await cipher.encryptV2(filteredCredential.data);
}View on GitHub (pinned to 5ac6606e81)
Solutions
- Wrap the credential object in an array: `[{ ... }]`.
- Alternatively use `--separate --input=dir/` where each file is one credential object.
Example fix
// before — f.json
{ "id": "x", "name": "..." }
// after — f.json
[ { "id": "x", "name": "..." } ] Defensive patterns
Strategy: type-guard
Validate before calling
function parseCredentialsFile(raw: string): Array<Partial<CredentialsEntity>> {
const parsed = JSON.parse(raw);
if (!Array.isArray(parsed)) {
throw new Error('Credentials file must contain a JSON array');
}
return parsed;
} Type guard
const isCredentialsArray = (v: unknown): v is Array<Record<string, unknown>> => Array.isArray(v) && v.every(item => typeof item === 'object' && item !== null);
Prevention
- Always wrap credentials in an array in export/import files, even for a single credential.
- Use --separate mode (one object per file) to avoid the array requirement.
When it happens
Trigger: `n8n import:credentials --input=f.json` where f.json contains a bare object `{...}` instead of `[{...}]`, or a non-credential JSON structure.
Common situations: Hand-editing an export down to a single object and forgetting the brackets; pulling a credential from an API that returns an object; using a workflow export file by mistake.
Related errors
- Provider connection data cannot be empty
- Provider connection data must be a JSON object
- ${flagName} must contain at least one property name.
- No importable properties found. Please check the --include f
- File does not seem to contain valid workflows.
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/7a3fcbeaa021244f.
Report an issue: GitHub.