{"record":{"id":"92656abe3dd12b26","repo":"Dokploy/dokploy","slug":"bad-request-92656a","errorCode":"BAD_REQUEST","errorMessage":"Provide a config or a dnsProviderId to test","messagePattern":"Provide a config or a dnsProviderId to test","errorType":"exception","errorClass":"TRPCError","httpStatus":400,"severity":"warning","filePath":"apps/dokploy/server/api/routers/dns-provider.ts","lineNumber":111,"sourceCode":"\t\t\tconfig: maskDnsProviderConfig(provider.config),\n\t\t}));\n\t}),\n\n\tone: withPermission(\"dnsProvider\", \"read\")\n\t\t.input(apiFindOneDnsProvider)\n\t\t.query(async ({ ctx, input }) => {\n\t\t\tconst provider = await findDnsProviderInOrganization(\n\t\t\t\tinput.dnsProviderId,\n\t\t\t\tctx.session.activeOrganizationId,\n\t\t\t);\n\t\t\treturn { ...provider, config: maskDnsProviderConfig(provider.config) };\n\t\t}),\n\n\ttestConnection: withPermission(\"dnsProvider\", \"create\")\n\t\t.input(apiTestDnsProvider)\n\t\t.mutation(async ({ ctx, input }) => {\n\t\t\tif (!input.config && !input.dnsProviderId) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: \"BAD_REQUEST\",\n\t\t\t\t\tmessage: \"Provide a config or a dnsProviderId to test\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tlet config = input.config;\n\t\t\tif (input.dnsProviderId) {\n\t\t\t\tconst provider = await findDnsProviderInOrganization(\n\t\t\t\t\tinput.dnsProviderId,\n\t\t\t\t\tctx.session.activeOrganizationId,\n\t\t\t\t);\n\t\t\t\tconfig = config\n\t\t\t\t\t? mergeDnsProviderConfig(config, provider.config)\n\t\t\t\t\t: provider.config;\n\t\t\t}\n\n\t\t\tawait testDnsProviderConnection(config!);\n\t\t\treturn true;","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/Dokploy/dokploy/blob/546686ea3587f12ec5652217dedd9f7960fb6d15/apps/dokploy/server/api/routers/dns-provider.ts#L93-L129","documentation":"Thrown by `dnsProvider.testConnection` when the mutation is called with neither an inline `config` nor an existing `dnsProviderId`. The procedure needs provider credentials to run a DNS test query, and with both inputs absent there is nothing to test, so it fails fast with BAD_REQUEST before touching any DNS API.","triggerScenarios":"Calling `dnsProvider.testConnection` with an empty payload `{}`; passing only whitespace/empty provider fields so `input.config` is falsy while omitting `dnsProviderId`; frontend sending the test request before the form has produced a config object.","commonSituations":"UI 'Test connection' button enabled before any provider is selected or credentials typed; migration scripts calling the endpoint with a bare object; Zod schema treating an all-optional config as valid (empty object passes validation but fails this runtime check).","solutions":["Pass an inline config (provider, credentials, etc.) when testing unsaved credentials","Or pass the `dnsProviderId` of a saved provider to test its stored credentials","Guard the UI: disable the Test button until the form yields a non-empty config or a saved provider is chosen","Fix clients that send `{}` — log the payload before calling to catch this early"],"exampleFix":"// before\nawait dnsProvider.testConnection.mutate({});\n// after\nawait dnsProvider.testConnection.mutate({\n  config: { provider: 'cloudflare', cloudflareApiToken: token },\n});\n// or, for a saved provider:\nawait dnsProvider.testConnection.mutate({ dnsProviderId });","handlingStrategy":"validation","validationCode":"if (!config && !dnsProviderId) {\n  throw new Error('provide a config or dnsProviderId to test');\n}\nawait dnsProvider.testConnection.mutate(config ? { config } : { dnsProviderId });","typeGuard":"const hasTestInput = (\n  i: { config?: unknown; dnsProviderId?: string },\n): i is { config: NonNullable<typeof i.config> } | { dnsProviderId: string } =>\n  Boolean(i.config ?? i.dnsProviderId);","tryCatchPattern":"try {\n  await dnsProvider.testConnection.mutate(payload);\n} catch (e) {\n  if (e instanceof TRPCClientError && e.data?.code === 'BAD_REQUEST') {\n    // populate the form config or select a saved provider, then retry\n  }\n}","preventionTips":["Disable the Test button until a config or saved provider is selected","Validate on the client that at least one input is present","Log outgoing payloads during development to catch empty objects"],"tags":["dokploy","trpc","dns-provider","validation","bad-request"],"backgroundTag":"missing-required-request-parameter","analyzedSha":"546686ea3587f12ec5652217dedd9f7960fb6d15","analyzedAt":"2026-08-27T05:18:58.095Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}