Dokploy/dokploy · warning · TRPCError

BAD_REQUEST

BAD_REQUEST

Error message

Provide a config or a vaultProviderId to test

What it means

Thrown by Dokploy's vault-provider testConnection mutation when the input contains neither an inline config object nor a vaultProviderId. The endpoint can test a draft configuration (config) or an already-saved provider (vaultProviderId), and requires at least one.

Source

Thrown at apps/dokploy/server/api/routers/vault-provider.ts:106

			config: maskVaultProviderConfig(provider.config),
		}));
	}),

	one: withPermission("vaultProvider", "read")
		.input(apiFindOneVaultProvider)
		.query(async ({ ctx, input }) => {
			const provider = await findVaultProviderInOrganization(
				input.vaultProviderId,
				ctx.session.activeOrganizationId,
			);
			return { ...provider, config: maskVaultProviderConfig(provider.config) };
		}),

	testConnection: withPermission("vaultProvider", "create")
		.input(apiTestVaultProvider)
		.mutation(async ({ ctx, input }) => {
			if (!input.config && !input.vaultProviderId) {
				throw new TRPCError({
					code: "BAD_REQUEST",
					message: "Provide a config or a vaultProviderId to test",
				});
			}

			let config = input.config;
			if (input.vaultProviderId) {
				const provider = await findVaultProviderInOrganization(
					input.vaultProviderId,
					ctx.session.activeOrganizationId,
				);
				config = config
					? mergeVaultProviderConfig(config, provider.config)
					: provider.config;
			}

			await testVaultProviderConnection(config!);
			return true;

View on GitHub (pinned to 546686ea35)

Solutions

  1. Pass the full provider config object from the form, or the id of an existing saved vault provider
  2. Disable the Test button until one of the two is present
  3. Validate client-side before calling the mutation

Example fix

// before
await trpc.vaultProvider.testConnection.mutate({ projectId, environmentId });

// after
await trpc.vaultProvider.testConnection.mutate({
  projectId,
  environmentId,
  config: { provider: 'hashicorp-vault', url, token, ... },
});
Defensive patterns

Strategy: validation

Validate before calling

if (form.config || selectedProviderId) {
  await trpc.vaultProvider.testConnection.mutate({
    projectId, environmentId,
    config: form.config ?? undefined,
    vaultProviderId: selectedProviderId ?? undefined,
  });
}

Type guard

const canTest = (i: { config?: unknown; vaultProviderId?: string }) =>
  Boolean(i.config) || Boolean(i.vaultProviderId);

Try / catch

catch (e) { if (e?.data?.code === 'BAD_REQUEST') highlightEmptyForm(); else throw e; }

Prevention

When it happens

Trigger: Calling testConnection with {} or with both config and vaultProviderId absent — e.g. a 'Test connection' button clicked before any form fields were filled and no saved provider selected.

Common situations: UI submitting the test before form state hydrates; conditional form where the saved-provider select and the manual config fields are both empty; API consumers assuming testConnection defaults to some provider.

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


AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27). Data as JSON: /api/errors/6cce5b8b6d7e61b5. Report an issue: GitHub.