ToolJet/ToolJet · warning · Error

Error

Error message

Error

What it means

In testConnection the plugin calls got(...) and then checks `if (!client) throw new Error('Error')`. Because got resolves with a Response object on success and rejects (throws) on any HTTP/network failure, a falsy return is effectively unreachable — the guard is dead defensive code, and its message ('Error') conveys no diagnostic information.

Source

Thrown at plugins/packages/couchdb/lib/index.ts:129

    }

    return {
      status: 'ok',
      data: result,
    };
  }

  async testConnection(sourceOptions: SourceOptions): Promise<ConnectionTestResult> {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const { username, password, port, host, database, protocol } = sourceOptions;
    const combined = `${username}:${password}`;
    const key = Buffer.from(combined).toString('base64');
    const client = await got(`${protocol}://${host}:${port}/_all_dbs`, {
      method: 'get',
      headers: { Authorization: `Basic ${key}` },
    });
    if (!client) {
      throw new Error('Error');
    }

    return {
      status: 'ok',
    };
  }

  private parseJSON(json?: string): object {
    if (!json) return {};

    return JSON5.parse(json);
  }
}

View on GitHub (pinned to 20602a8e10)

Solutions

  1. Look at the real thrown error from got (status code / ECONNREFUSED) — the 'Error' message is not the root cause.
  2. Verify protocol, host, port, username, and password in sourceOptions.
  3. Confirm the CouchDB instance is reachable from the ToolJet server.
  4. If maintaining this plugin, replace the generic check with a proper status-code assertion that includes detail.
  5. Remove the dead guard since got never returns falsy.

Example fix

// before
const client = await got(url, { method: 'get', headers });
if (!client) {
  throw new Error('Error');
}
// after - assert on a meaningful status, or rely on got throwing on non-2xx
const res = await got(url, { method: 'get', headers, throwHttpErrors: true });
if (res.statusCode !== 200) {
  throw new Error(`CouchDB connection test failed: HTTP ${res.statusCode}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

async function probeCouch(sourceOptions: any) {
  const { protocol, host, port, username, password } = sourceOptions;
  const key = Buffer.from(`${username}:${password}`).toString('base64');
  try {
    const res = await got(`${protocol}://${host}:${port}/_all_dbs`, { headers: { Authorization: `Basic ${key}` } });
    if (!Array.isArray(JSON.parse(res.body))) throw new Error('CouchDB did not return a database list');
  } catch (err) {
    throw new Error(`CouchDB unreachable: ${err.message}`);
  }
}

Type guard

function isGotHttpError(err: any): boolean {
  return err?.name === 'HTTPError';
}

Try / catch

try {
  await couchdb.testConnection(sourceOptions);
} catch (err) {
  // The 'Error' message is dead code; the real cause is a got HTTPError/connection error.
  const status = err?.response?.statusCode;
  if (status === 401) throw new Error('CouchDB credentials are invalid');
  if (status === 404) throw new Error('CouchDB endpoint not found');
  if (err?.code === 'ECONNREFUSED') throw new Error('CouchDB host/port unreachable');
  throw err;
}

Prevention

When it happens

Trigger: Theoretically fires only if got returned a falsy value, which it does not in normal operation. In practice every real failure (bad credentials, unreachable host) surfaces as a got rejection that escapes this function before the check runs.

Common situations: A developer sees 'Error' with no context during connection testing; the actual cause is a got HTTPError (401/404) or a connection error that was thrown, not a falsy client.

Related errors


AI-assisted analysis of ToolJet/ToolJet@20602a8e10 (2026-08-13). Data as JSON: /api/errors/ea5557f44445c518. Report an issue: GitHub.