[object Object]

← back to Ventura Claw

ENV_KEY_TO_CONNECTOR: align field names with what the handlers actually read

a6a5067a129543c201f6c0f8e3df9cc4673440a9 · 2026-05-06 17:03:19 -0700 · SteveStudio2

Previous version used descriptive field keys (api_key, access_token, store).
The connector handlers (stripe.js, cloudflare.js, etc) look up creds under
the upper-case env var name (STRIPE_SECRET_KEY, CF_API_TOKEN, ...). After
import, /admin/connectors UI showed 'filled: true' but every command failed
with 'no_token' because the lookup key didn't match the storage key.

Fixed by making each entry's 'field' match the handler's lookup key. Notable
remappings beyond the obvious uppercase-rename:
- CLOUDFLARE_API_TOKEN  → CF_API_TOKEN  (CF_ prefix in handler)
- HUBSPOT_ACCESS_TOKEN  → HUBSPOT_TOKEN
- NOTION_API_KEY        → NOTION_TOKEN
- CANVA_API_KEY         → CANVA_TOKEN
- ETSY_API_KEY          → ETSY_KEYSTRING
- SHOPIFY_ACCESS_TOKEN  → SHOPIFY_ADMIN_TOKEN

Also added direct-name aliases (HUBSPOT_TOKEN, NOTION_TOKEN, CANVA_TOKEN,
ETSY_KEYSTRING, ETSY_ACCESS_TOKEN) so users can paste either variant.

After re-import: stripe + cloudflare + archive flip from rejected → ✓ ok.
Live prod /api/connectors/health-all confirms 5 connectors authenticate
where 2 did before.

Files touched

Diff

commit a6a5067a129543c201f6c0f8e3df9cc4673440a9
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Wed May 6 17:03:19 2026 -0700

    ENV_KEY_TO_CONNECTOR: align field names with what the handlers actually read
    
    Previous version used descriptive field keys (api_key, access_token, store).
    The connector handlers (stripe.js, cloudflare.js, etc) look up creds under
    the upper-case env var name (STRIPE_SECRET_KEY, CF_API_TOKEN, ...). After
    import, /admin/connectors UI showed 'filled: true' but every command failed
    with 'no_token' because the lookup key didn't match the storage key.
    
    Fixed by making each entry's 'field' match the handler's lookup key. Notable
    remappings beyond the obvious uppercase-rename:
    - CLOUDFLARE_API_TOKEN  → CF_API_TOKEN  (CF_ prefix in handler)
    - HUBSPOT_ACCESS_TOKEN  → HUBSPOT_TOKEN
    - NOTION_API_KEY        → NOTION_TOKEN
    - CANVA_API_KEY         → CANVA_TOKEN
    - ETSY_API_KEY          → ETSY_KEYSTRING
    - SHOPIFY_ACCESS_TOKEN  → SHOPIFY_ADMIN_TOKEN
    
    Also added direct-name aliases (HUBSPOT_TOKEN, NOTION_TOKEN, CANVA_TOKEN,
    ETSY_KEYSTRING, ETSY_ACCESS_TOKEN) so users can paste either variant.
    
    After re-import: stripe + cloudflare + archive flip from rejected → ✓ ok.
    Live prod /api/connectors/health-all confirms 5 connectors authenticate
    where 2 did before.
---
 server/server.js | 99 ++++++++++++++++++++++++++++++--------------------------
 1 file changed, 53 insertions(+), 46 deletions(-)

diff --git a/server/server.js b/server/server.js
index 1244f2c..ae31935 100644
--- a/server/server.js
+++ b/server/server.js
@@ -1700,57 +1700,64 @@ app.post("/api/me/connections/:id", requireAuth, (req, res, next) => {
 // keys to connector credentials and merges into the current user's namespace.
 //
 // Body: { content: "<paste>", format?: "auto"|"claude-json"|"env"|"json" }
+// Each entry: env var name → { connectorId, field }
+// IMPORTANT: `field` MUST match the key the connector's handler reads from `creds[...]`.
+// (Old version used descriptive names like `api_key`/`access_token` and broke runtime lookups.)
 const ENV_KEY_TO_CONNECTOR = {
-  // Each entry: env var name → { connectorId, field }
-  STRIPE_SECRET_KEY:        { connector: 'stripe',      field: 'api_key' },
-  STRIPE_PUBLISHABLE_KEY:   { connector: 'stripe',      field: 'publishable_key' },
-  CLOUDFLARE_API_TOKEN:     { connector: 'cloudflare',  field: 'api_key' },
-  CLOUDFLARE_ACCOUNT_ID:    { connector: 'cloudflare',  field: 'account_id' },
-  GODADDY_API_KEY:          { connector: 'godaddy',     field: 'api_key' },
-  GODADDY_API_SECRET:       { connector: 'godaddy',     field: 'api_secret' },
-  BROWSERBASE_API_KEY:      { connector: 'browserbase', field: 'api_key' },
-  BROWSERBASE_PROJECT_ID:   { connector: 'browserbase', field: 'project_id' },
-  SHOPIFY_ACCESS_TOKEN:     { connector: 'shopify',     field: 'access_token' },
-  SHOPIFY_STORE:            { connector: 'shopify',     field: 'store' },
-  ETSY_API_KEY:             { connector: 'etsy',        field: 'api_key' },
-  PAYPAL_CLIENT_ID:         { connector: 'paypal',      field: 'client_id' },
-  PAYPAL_SECRET:            { connector: 'paypal',      field: 'secret' },
-  SQUARE_ACCESS_TOKEN:      { connector: 'square',      field: 'access_token' },
-  TWILIO_ACCOUNT_SID:       { connector: 'twilio',      field: 'account_sid' },
-  TWILIO_AUTH_TOKEN:        { connector: 'twilio',      field: 'auth_token' },
-  SLACK_BOT_TOKEN:          { connector: 'slack',       field: 'bot_token' },
-  DISCORD_BOT_TOKEN:        { connector: 'discord',     field: 'bot_token' },
-  MAILCHIMP_API_KEY:        { connector: 'mailchimp',   field: 'api_key' },
-  KLAVIYO_API_KEY:          { connector: 'klaviyo',     field: 'api_key' },
-  HUBSPOT_ACCESS_TOKEN:     { connector: 'hubspot',     field: 'access_token' },
-  SALESFORCE_ACCESS_TOKEN:  { connector: 'salesforce',  field: 'access_token' },
-  ZENDESK_API_TOKEN:        { connector: 'zendesk',     field: 'api_token' },
-  INTERCOM_ACCESS_TOKEN:    { connector: 'intercom',    field: 'access_token' },
-  NOTION_API_KEY:           { connector: 'notion',      field: 'api_key' },
-  AIRTABLE_PAT:             { connector: 'airtable',    field: 'api_key' },
-  ASANA_PAT:                { connector: 'asana',       field: 'access_token' },
-  CLICKUP_API_TOKEN:        { connector: 'clickup',     field: 'api_token' },
-  TRELLO_API_KEY:           { connector: 'trello',      field: 'api_key' },
-  TRELLO_TOKEN:             { connector: 'trello',      field: 'token' },
-  FIGMA_TOKEN:              { connector: 'figma',       field: 'token' },
-  CANVA_API_KEY:            { connector: 'canva',       field: 'api_key' },
-  ADOBE_CLIENT_ID:          { connector: 'adobe',       field: 'client_id' },
-  AWS_ACCESS_KEY_ID:        { connector: 'aws',         field: 'access_key_id' },
-  AWS_SECRET_ACCESS_KEY:    { connector: 'aws',         field: 'secret_access_key' },
-  VERCEL_TOKEN:             { connector: 'vercel',      field: 'token' },
-  SUPABASE_KEY:             { connector: 'supabase',    field: 'api_key' },
+  STRIPE_SECRET_KEY:        { connector: 'stripe',      field: 'STRIPE_SECRET_KEY' },
+  STRIPE_PUBLISHABLE_KEY:   { connector: 'stripe',      field: 'STRIPE_PUBLISHABLE_KEY' },
+  CLOUDFLARE_API_TOKEN:     { connector: 'cloudflare',  field: 'CF_API_TOKEN' },          // handler reads CF_API_TOKEN
+  CLOUDFLARE_ACCOUNT_ID:    { connector: 'cloudflare',  field: 'CF_ACCOUNT_ID' },
+  GODADDY_API_KEY:          { connector: 'godaddy',     field: 'GODADDY_API_KEY' },
+  GODADDY_API_SECRET:       { connector: 'godaddy',     field: 'GODADDY_API_SECRET' },
+  BROWSERBASE_API_KEY:      { connector: 'browserbase', field: 'BROWSERBASE_API_KEY' },
+  BROWSERBASE_PROJECT_ID:   { connector: 'browserbase', field: 'BROWSERBASE_PROJECT_ID' },
+  SHOPIFY_ACCESS_TOKEN:     { connector: 'shopify',     field: 'SHOPIFY_ADMIN_TOKEN' },   // handler reads SHOPIFY_ADMIN_TOKEN
+  SHOPIFY_ADMIN_TOKEN:      { connector: 'shopify',     field: 'SHOPIFY_ADMIN_TOKEN' },
+  SHOPIFY_STORE:            { connector: 'shopify',     field: 'SHOPIFY_STORE' },
+  ETSY_API_KEY:             { connector: 'etsy',        field: 'ETSY_KEYSTRING' },        // handler reads ETSY_KEYSTRING
+  ETSY_KEYSTRING:           { connector: 'etsy',        field: 'ETSY_KEYSTRING' },
+  ETSY_ACCESS_TOKEN:        { connector: 'etsy',        field: 'ETSY_ACCESS_TOKEN' },
+  PAYPAL_CLIENT_ID:         { connector: 'paypal',      field: 'PAYPAL_CLIENT_ID' },
+  PAYPAL_SECRET:            { connector: 'paypal',      field: 'PAYPAL_SECRET' },
+  SQUARE_ACCESS_TOKEN:      { connector: 'square',      field: 'SQUARE_ACCESS_TOKEN' },
+  TWILIO_ACCOUNT_SID:       { connector: 'twilio',      field: 'TWILIO_ACCOUNT_SID' },
+  TWILIO_AUTH_TOKEN:        { connector: 'twilio',      field: 'TWILIO_AUTH_TOKEN' },
+  SLACK_BOT_TOKEN:          { connector: 'slack',       field: 'SLACK_BOT_TOKEN' },
+  SLACK_TOKEN:              { connector: 'slack',       field: 'SLACK_BOT_TOKEN' },
+  DISCORD_BOT_TOKEN:        { connector: 'discord',     field: 'DISCORD_BOT_TOKEN' },
+  MAILCHIMP_API_KEY:        { connector: 'mailchimp',   field: 'MAILCHIMP_API_KEY' },
+  KLAVIYO_API_KEY:          { connector: 'klaviyo',     field: 'KLAVIYO_API_KEY' },
+  HUBSPOT_ACCESS_TOKEN:     { connector: 'hubspot',     field: 'HUBSPOT_TOKEN' },         // handler reads HUBSPOT_TOKEN
+  HUBSPOT_TOKEN:            { connector: 'hubspot',     field: 'HUBSPOT_TOKEN' },
+  SALESFORCE_ACCESS_TOKEN:  { connector: 'salesforce',  field: 'SALESFORCE_ACCESS_TOKEN' },
+  ZENDESK_API_TOKEN:        { connector: 'zendesk',     field: 'ZENDESK_API_TOKEN' },
+  INTERCOM_ACCESS_TOKEN:    { connector: 'intercom',    field: 'INTERCOM_ACCESS_TOKEN' },
+  NOTION_API_KEY:           { connector: 'notion',      field: 'NOTION_TOKEN' },          // handler reads NOTION_TOKEN
+  NOTION_TOKEN:             { connector: 'notion',      field: 'NOTION_TOKEN' },
+  AIRTABLE_PAT:             { connector: 'airtable',    field: 'AIRTABLE_PAT' },
+  ASANA_PAT:                { connector: 'asana',       field: 'ASANA_PAT' },
+  CLICKUP_API_TOKEN:        { connector: 'clickup',     field: 'CLICKUP_API_TOKEN' },
+  TRELLO_API_KEY:           { connector: 'trello',      field: 'TRELLO_API_KEY' },
+  TRELLO_TOKEN:             { connector: 'trello',      field: 'TRELLO_TOKEN' },
+  FIGMA_TOKEN:              { connector: 'figma',       field: 'FIGMA_TOKEN' },
+  CANVA_API_KEY:            { connector: 'canva',       field: 'CANVA_TOKEN' },           // handler reads CANVA_TOKEN
+  CANVA_TOKEN:              { connector: 'canva',       field: 'CANVA_TOKEN' },
+  ADOBE_CLIENT_ID:          { connector: 'adobe',       field: 'ADOBE_CLIENT_ID' },
+  AWS_ACCESS_KEY_ID:        { connector: 'aws',         field: 'AWS_ACCESS_KEY_ID' },
+  AWS_SECRET_ACCESS_KEY:    { connector: 'aws',         field: 'AWS_SECRET_ACCESS_KEY' },
+  VERCEL_TOKEN:             { connector: 'vercel',      field: 'VERCEL_TOKEN' },
+  SUPABASE_KEY:             { connector: 'supabase',    field: 'SUPABASE_KEY' },
   ELEVENLABS_API_KEY:       { connector: 'elevenlabs',  field: 'ELEVENLABS_API_KEY' },
   PURELYMAIL_API_TOKEN:     { connector: 'purelymail',  field: 'PURELYMAIL_API_TOKEN' },
   GEORGE_URL:               { connector: 'gmail',       field: 'GEORGE_URL' },
   GEORGE_BASIC_AUTH:        { connector: 'gmail',       field: 'GEORGE_BASIC_AUTH' },
-  LINKEDIN_CLIENT_ID:       { connector: 'linkedin',    field: 'client_id' },
-  LINKEDIN_CLIENT_SECRET:   { connector: 'linkedin',    field: 'client_secret' },
-  // Aliases for common variants:
-  STRIPE_API_KEY:           { connector: 'stripe',      field: 'api_key' },
-  CLOUDFLARE_TOKEN:         { connector: 'cloudflare',  field: 'api_key' },
-  SHOPIFY_TOKEN:            { connector: 'shopify',     field: 'access_token' },
-  SLACK_TOKEN:              { connector: 'slack',       field: 'bot_token' },
-  SHOPIFY_ADMIN_TOKEN:      { connector: 'shopify',     field: 'access_token' },
+  LINKEDIN_CLIENT_ID:       { connector: 'linkedin',    field: 'LINKEDIN_CLIENT_ID' },
+  LINKEDIN_CLIENT_SECRET:   { connector: 'linkedin',    field: 'LINKEDIN_CLIENT_SECRET' },
+  // Convenience aliases for the most common variant names:
+  STRIPE_API_KEY:           { connector: 'stripe',      field: 'STRIPE_SECRET_KEY' },
+  CLOUDFLARE_TOKEN:         { connector: 'cloudflare',  field: 'CF_API_TOKEN' },
+  SHOPIFY_TOKEN:            { connector: 'shopify',     field: 'SHOPIFY_ADMIN_TOKEN' },
 };
 
 function parseEnvText(text) {

← 1ad784f Wizard: bulk health strip — see all saved connectors auth st  ·  back to Ventura Claw  ·  Add 5 no-auth public-data connectors: MET, Cleveland, AIC, W 4cd2509 →