n8n-io/n8n · error · Error

No captured fields found for credentialsKey "${args.credenti

Error message

No captured fields found for credentialsKey "${args.credentialsKey}". Call browser_capture_secret first.

What it means

Thrown by browser_create_credential when context.secretsBuffer.getFields(credentialsKey) returns falsy — no secrets were captured for the given key. The create-credential tool assembles buffered secrets into a credential; calling it before any browser_capture_secret for the same credentialsKey leaves the buffer empty.

Source

Thrown at packages/@n8n/mcp-browser/src/tools/credential.ts:137

			.describe('Clear the session buffer for credentialsKey after success (default: true)'),
	})
	.describe('Assemble buffered secrets into an n8n credential');

function browserCreateCredential(
	_connection: BrowserConnection,
): ToolDefinition<typeof browserCreateCredentialSchema> {
	return {
		name: 'browser_create_credential',
		description:
			'Assemble secrets captured with browser_capture_secret into a new n8n credential. Literal fields go in `data`; fields that must come from the buffer go in `resolveData` (leaf values are buffer field names). The buffer is cleared after success unless clear=false.',
		inputSchema: browserCreateCredentialSchema,
		async execute(args, context: ToolContext) {
			requireSecretsBuffer(context);
			requireCreateCredential(context);

			const captured = context.secretsBuffer.getFields(args.credentialsKey);
			if (!captured) {
				throw new Error(
					`No captured fields found for credentialsKey "${args.credentialsKey}". Call browser_capture_secret first.`,
				);
			}

			const resolvedSecrets = args.resolveData ? resolveSecrets(args.resolveData, captured) : {};
			const mergedData = deepMerge(args.data ?? {}, resolvedSecrets);

			const credential = await context.createCredential({
				name: args.name,
				type: args.type,
				data: mergedData,
				projectId: args.projectId,
			} satisfies CreateCredentialPayload);

			if (args.clear !== false) {
				context.secretsBuffer.clear(args.credentialsKey);
			}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Call browser_capture_secret for every required field under the same credentialsKey before browser_create_credential.
  2. Pass clear=false on the first create call if you need to issue a second create for the same buffer.
  3. Verify the credentialsKey string matches exactly between capture and create calls.

Example fix

// before — create without prior capture
await createCredential({ credentialsKey: 'gcp', type: 'googleApi', name: 'GCP' }); // throws

// after — capture fields first
await captureSecret({ credentialsKey: 'gcp', field: 'clientId', ... });
await createCredential({ credentialsKey: 'gcp', type: 'googleApi', name: 'GCP' });
Defensive patterns

Strategy: validation

Validate before calling

const captured = secretsBuffer.getFields(credentialsKey);
if (!captured) { throw new Error('Capture required fields first'); }

Type guard

function hasCapturedFields(buf: SecretsBuffer, key: string): boolean {
  return buf.getFields(key) !== undefined;
}

Try / catch

try {
  await createCredential({ credentialsKey, ... });
} catch (e) {
  if (/No captured fields/.test(e.message)) {
    await captureSecret({ credentialsKey, field: 'x', ... });
    await createCredential({ credentialsKey, ... });
  } else throw e;
}

Prevention

When it happens

Trigger: Invoking browser_create_credential for a credentialsKey that was never populated via browser_capture_secret, or whose buffer was already cleared by a prior create call (clear defaults to true).

Common situations: Agent calls create before capture. Two create calls for the same key — the second fails because the first cleared the buffer. credentialsKey typo or mismatch between capture and create. Buffer cleared by disconnect/reconnect.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/b5425f0e07cb4e91. Report an issue: GitHub.