nexu-io/open-design · error · ConnectorServiceError
CONNECTOR_NOT_FOUND
CONNECTOR_NOT_FOUND
Error message
connector not found
What it means
Thrown by ConnectorService.getConnector() when getDefinition(connectorId) resolves to undefined, i.e. no catalog entry matches the id. It is a ConnectorServiceError with code CONNECTOR_NOT_FOUND and HTTP 404. This is the read path behind the GET connector detail route and the 'od connector get' CLI.
Source
Thrown at apps/daemon/src/connectors/service.ts:640
if (options.refresh) composioConnectorProvider.clearDiscoveryCache();
const definitions = options.refresh && !options.hydrateTools
? await composioConnectorProvider.refreshCatalog(options.signal)
: options.hydrateTools
? await this.listHydratedDefinitions(options.signal)
: await this.listDefinitions(options.signal);
return {
connectors: definitions.map((definition) => this.toDetail(definition)),
meta: {
provider: 'composio',
...(options.refresh ? { refreshRequested: true } : {}),
},
};
}
async getConnector(connectorId: string, signal?: AbortSignal): Promise<ConnectorDetail> {
const definition = await this.getDefinition(connectorId, signal);
if (!definition) {
throw new ConnectorServiceError('CONNECTOR_NOT_FOUND', 'connector not found', 404);
}
return this.toDetail(definition);
}
async getHydratedConnector(connectorId: string, signal?: AbortSignal): Promise<ConnectorDetail> {
const definition = await this.getHydratedDefinition(connectorId, signal);
if (!definition) {
throw new ConnectorServiceError('CONNECTOR_NOT_FOUND', 'connector not found', 404);
}
return this.toDetail(definition);
}
async getPreviewConnector(connectorId: string, options: { toolsLimit: number; toolsCursor?: string; signal?: AbortSignal }): Promise<ConnectorDetail> {
const definition = await this.getPreviewDefinition(connectorId, options);
if (!definition) {
throw new ConnectorServiceError('CONNECTOR_NOT_FOUND', 'connector not found', 404);
}
return this.toDetail(definition);View on GitHub (pinned to 5be4028344)
Solutions
- List connectors first (listConnectors) and copy the exact id from the catalog.
- Pass { refresh: true } to listConnectors to force a Composio catalog refresh, then retry getConnector.
- Verify the connector is not disabled/removed upstream in the Composio dashboard.
- Normalize the id (trim, lowercase only if the catalog uses lowercase ids) before the call.
Example fix
// before
await connectorService.getConnector('Gihub'); // typo
// throws CONNECTOR_NOT_FOUND
// after
const { connectors } = await connectorService.listConnectors({ refresh: true });
const id = connectors.find((c) => c.name.toLowerCase().includes('github'))?.id;
if (!id) throw new Error('github connector unavailable');
await connectorService.getConnector(id); Defensive patterns
Strategy: validation
Validate before calling
async function resolveConnectorId(connectorService: ConnectorService, candidate: string): Promise<string | null> {
const { connectors } = await connectorService.listConnectors();
const found = connectors.find((c) => c.id === candidate);
return found ? found.id : null;
}
const id = await resolveConnectorId(connectorService, rawId);
if (!id) throw new Error(`unknown connector: ${rawId}`);
await connectorService.getConnector(id); Type guard
async function connectorExists(connectorService: ConnectorService, id: string): Promise<boolean> {
const { connectors } = await connectorService.listConnectors();
return connectors.some((c) => c.id === id);
}
// if (!(await connectorExists(connectorService, id))) return 'connector not available'; Try / catch
try {
return await connectorService.getConnector(id);
} catch (error) {
if (error instanceof ConnectorServiceError && error.code === 'CONNECTOR_NOT_FOUND') {
await connectorService.listConnectors({ refresh: true });
return connectorService.getConnector(id); // one retry after refresh
}
throw error;
} Prevention
- Always source connector ids from listConnectors() output, never from hard-coded strings.
- Pass { refresh: true } when the id may be stale (older session, different environment).
- Trim/normalize ids from user input before lookup.
When it happens
Trigger: Calling getConnector(connectorId) with an id that is not present in the local fast catalog nor returned by Composio after a refresh, e.g. a typo, a stale id from an older catalog, or an id from a different environment.
Common situations: Hard-coded connector id drifted after a catalog refresh; user typed/pasted an id; the Composio catalog failed to load and only the static catalog is available; cross-environment id mismatch (beta vs stable).
Related errors
- CONNECTOR_OUTPUT_TOO_LARGE
- CONNECTOR_EXECUTION_FAILED
- CONNECTOR_DISABLED
- CONNECTOR_NOT_CONNECTED
- CONNECTOR_TOOL_NOT_FOUND
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/e8e4d6e66bfd0e39.
Report an issue: GitHub.