From 618b87fc10365f581be829c026f2a2e8bb0e906a Mon Sep 17 00:00:00 2001 From: William Mantly Date: Fri, 10 Jul 2026 23:03:38 -0400 Subject: [PATCH] Fix Porkbun (and other zoneless providers) domain sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updateDomains passed `zoneId: domain.zoneId` unconditionally. Providers with no zone concept (Porkbun, DigitalOcean) return domains without a zoneId, so this sent an explicit `undefined`, which model-redis' processKeys rejects ("zoneId is not string type") and aborts the whole sync with a 422. Cloudflare was unaffected because its domains carry a real zoneId string. DnsProvider.create's catch only re-threw UnauthorizedDnsApi and swallowed everything else, returning undefined — so the route then crashed on `item.id` with an opaque "Cannot read properties of undefined" instead of the real validation error. - Omit zoneId from the Domain payload when the provider doesn't supply one. - Re-throw non-Unauthorized errors from create so failures surface properly. Co-Authored-By: Claude Opus 4.8 --- nodejs/models/dns_provider.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/nodejs/models/dns_provider.js b/nodejs/models/dns_provider.js index 105bdf8..7d1eefc 100644 --- a/nodejs/models/dns_provider.js +++ b/nodejs/models/dns_provider.js @@ -96,12 +96,15 @@ class DnsProvider extends Table{ }catch(error){ if(error.name === 'UnauthorizedDnsApi'){ let keys = []; - console.log('Provider', Provider) for(let key in Provider._keyMap){ keys.push({'key': key, message: 'Invalid Key'}) } throw this.errors.ObjectValidateError(keys, "API rejected key"); } + // Don't swallow other failures (e.g. a domain-sync validation error): + // returning undefined here made the route crash on `item.id` with an + // opaque message. Surface the real error to the caller instead. + throw error; } } @@ -145,7 +148,11 @@ class DnsProvider extends Table{ created_by: this.created_by, domain: domain.domain, dnsProvider_id: this.id, - zoneId: domain.zoneId, + // Only providers with a zone concept (e.g. Cloudflare) return a + // zoneId. Porkbun/DigitalOcean don't, and passing an explicit + // `undefined` trips model-redis' type check ("zoneId is not string + // type") and aborts the whole sync — so omit it when absent. + ...(domain.zoneId !== undefined ? {zoneId: domain.zoneId} : {}), }); } console.log('currentDomains:', currentDomains)