Skip to content

Commit 2b90218

Browse files
committed
fix(pitchbook): stop a rejected API key reaching block output and logs
PitchBook's 401 body echoes the submitted key back inside `message`. No PitchBook tool declared an `errorExtractor`, so the failure fell through to the generic chain, whose first entry returns `data.message` verbatim — putting the credential in the block error, the run log, and any agent context reading the failure. The existing scrubber sat in `transformResponse`, which never runs on a non-ok response. - add a `pitchbook-errors` extractor that replaces the unauthorized message with a fixed string, and wire it through all 91 tools - the extractor returns undefined unless the body carries a `message`, so a foreign 401 on the shared fallback chain is never labelled a PitchBook failure - correct `investor_preferences.preferredIndustry` to the shape the API returns - make `company_industries.emergingSpaces` opaque; its item shape is undocumented - reject a non-list of article ids instead of throwing a bare TypeError
1 parent 4a92779 commit 2b90218

94 files changed

Lines changed: 346 additions & 15 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/docs/content/docs/en/integrations/pitchbook.mdx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,6 @@ Retrieve the industry classification, verticals, keywords, and emerging spaces a
427427
|`description` | string | Vertical label |
428428
| `keywords` | array | Keywords associated with the company |
429429
| `emergingSpaces` | array | Analyst-defined emerging spaces the company is placed in |
430-
|`code` | string | Emerging space code |
431-
|`description` | string | Emerging space label |
432430

433431
### PitchBook Company Investors
434432

@@ -1840,8 +1838,14 @@ Retrieve what an investor targets: check size, deal size, valuation, revenue, ge
18401838
|`code` | string | Preference code |
18411839
|`description` | string | Preference label |
18421840
| `preferredIndustry` | array | Industries the investor targets |
1843-
|`code` | string | Industry code |
1844-
|`description` | string | Industry label |
1841+
|`industryCode` | json | Most specific industry classification |
1842+
|`industrySector` | object | Top-level sector |
1843+
|`code` | string | Sector code |
1844+
|`description` | string | Sector label |
1845+
|`industryGroup` | object | Industry group within the sector |
1846+
|`code` | string | Group code |
1847+
|`description` | string | Group label |
1848+
|`primary` | boolean | Whether this is the primary industry |
18451849
| `preferredDealTypes` | array | Deal types the investor targets |
18461850
|`code` | string | Deal type code |
18471851
|`description` | string | Deal type label |

apps/sim/tools/error-extractors.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,26 @@ const ERROR_EXTRACTORS: ErrorExtractorConfig[] = [
424424
return messages.length > 0 ? messages.join('; ') : undefined
425425
},
426426
},
427+
{
428+
id: 'pitchbook-errors',
429+
description:
430+
'PitchBook Public API error envelope: {reason, message}. An unauthorized response echoes the rejected key back inside `message` ("Active API key {KEY} not found"), so that case is replaced with a fixed string — the generic message fallback would otherwise put the credential in the block error, the run log, and any agent context reading the failure. Returns undefined unless the body carries a `message`, so that on the generic fallback chain — which every tool without an `errorExtractor` walks — a foreign 401 is never labelled a PitchBook auth failure',
431+
examples: ['PitchBook'],
432+
extract: (errorInfo) => {
433+
const data = errorInfo?.data
434+
if (!data || typeof data !== 'object' || Array.isArray(data)) return undefined
435+
436+
const reason = typeof data.reason === 'string' ? data.reason.trim() : ''
437+
const message = typeof data.message === 'string' ? data.message.trim() : ''
438+
if (!message) return undefined
439+
440+
if (errorInfo?.status === 401 || reason === 'UNAUTHORIZED') {
441+
return 'PitchBook rejected the API key. Check that the key is active and has API access.'
442+
}
443+
444+
return reason ? `${message} (${reason})` : message
445+
},
446+
},
427447
{
428448
id: 'splunk-errors',
429449
description:
@@ -533,6 +553,7 @@ export const ErrorExtractorId = {
533553
POSTHOG_ERRORS: 'posthog-errors',
534554
PROSPEO_ERRORS: 'prospeo-errors',
535555
CRUNCHBASE_ERRORS: 'crunchbase-errors',
556+
PITCHBOOK_ERRORS: 'pitchbook-errors',
536557
SPLUNK_ERRORS: 'splunk-errors',
537558
PLAIN_TEXT_DATA: 'plain-text-data',
538559
HTTP_STATUS_TEXT: 'http-status-text',

apps/sim/tools/pitchbook/company_active_investors.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ErrorExtractorId } from '@/tools/error-extractors'
12
import type { PitchbookProfileParams, PitchbookResponse } from '@/tools/pitchbook/types'
23
import { PITCHBOOK_API_BASE, pitchbookAuthHeaders, throwIfNotOk } from '@/tools/pitchbook/utils'
34
import type { ToolConfig } from '@/tools/types'
@@ -10,6 +11,7 @@ export const pitchbookCompanyActiveInvestorsTool: ToolConfig<
1011
name: 'PitchBook Company Active Investors',
1112
description: 'Retrieve only the investors currently holding a position in a company',
1213
version: '1.0.0',
14+
errorExtractor: ErrorExtractorId.PITCHBOOK_ERRORS,
1315

1416
params: {
1517
apiKey: {

apps/sim/tools/pitchbook/company_bio.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ErrorExtractorId } from '@/tools/error-extractors'
12
import type { PitchbookProfileParams, PitchbookResponse } from '@/tools/pitchbook/types'
23
import { PITCHBOOK_API_BASE, pitchbookAuthHeaders, throwIfNotOk } from '@/tools/pitchbook/utils'
34
import type { ToolConfig } from '@/tools/types'
@@ -8,6 +9,7 @@ export const pitchbookCompanyBioTool: ToolConfig<PitchbookProfileParams, Pitchbo
89
description:
910
'Retrieve the core profile of a company: names, description, HQ, status, headcount, total raised, and social links',
1011
version: '1.0.0',
12+
errorExtractor: ErrorExtractorId.PITCHBOOK_ERRORS,
1113

1214
params: {
1315
apiKey: {

apps/sim/tools/pitchbook/company_deal_service_providers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ErrorExtractorId } from '@/tools/error-extractors'
12
import type { PitchbookProfileParams, PitchbookResponse } from '@/tools/pitchbook/types'
23
import { PITCHBOOK_API_BASE, pitchbookAuthHeaders, throwIfNotOk } from '@/tools/pitchbook/utils'
34
import type { ToolConfig } from '@/tools/types'
@@ -11,6 +12,7 @@ export const pitchbookCompanyDealServiceProvidersTool: ToolConfig<
1112
description:
1213
'Retrieve the service providers that worked on a company deals, and what each was hired for',
1314
version: '1.0.0',
15+
errorExtractor: ErrorExtractorId.PITCHBOOK_ERRORS,
1416

1517
params: {
1618
apiKey: {

apps/sim/tools/pitchbook/company_deals.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ErrorExtractorId } from '@/tools/error-extractors'
12
import type { PitchbookProfileParams, PitchbookResponse } from '@/tools/pitchbook/types'
23
import { PITCHBOOK_API_BASE, pitchbookAuthHeaders, throwIfNotOk } from '@/tools/pitchbook/utils'
34
import type { ToolConfig } from '@/tools/types'
@@ -8,6 +9,7 @@ export const pitchbookCompanyDealsTool: ToolConfig<PitchbookProfileParams, Pitch
89
description:
910
'Retrieve every deal a company has been involved in, in chronological order with its deal type',
1011
version: '1.0.0',
12+
errorExtractor: ErrorExtractorId.PITCHBOOK_ERRORS,
1113

1214
params: {
1315
apiKey: {

apps/sim/tools/pitchbook/company_financials.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ErrorExtractorId } from '@/tools/error-extractors'
12
import type { PitchbookProfileParams, PitchbookResponse } from '@/tools/pitchbook/types'
23
import { PITCHBOOK_API_BASE, pitchbookAuthHeaders, throwIfNotOk } from '@/tools/pitchbook/utils'
34
import type { ToolConfig } from '@/tools/types'
@@ -9,6 +10,7 @@ export const pitchbookCompanyFinancialsTool: ToolConfig<PitchbookProfileParams,
910
description:
1011
'Retrieve reported financials for a private company across every available fiscal period. Annual data is returned by default.',
1112
version: '1.0.0',
13+
errorExtractor: ErrorExtractorId.PITCHBOOK_ERRORS,
1214

1315
params: {
1416
apiKey: {

apps/sim/tools/pitchbook/company_general_service_providers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ErrorExtractorId } from '@/tools/error-extractors'
12
import type { PitchbookProfileParams, PitchbookResponse } from '@/tools/pitchbook/types'
23
import { PITCHBOOK_API_BASE, pitchbookAuthHeaders, throwIfNotOk } from '@/tools/pitchbook/utils'
34
import type { ToolConfig } from '@/tools/types'
@@ -10,6 +11,7 @@ export const pitchbookCompanyGeneralServiceProvidersTool: ToolConfig<
1011
name: 'PitchBook Company General Service Providers',
1112
description: 'Retrieve the current and former general service providers engaged by a company',
1213
version: '1.0.0',
14+
errorExtractor: ErrorExtractorId.PITCHBOOK_ERRORS,
1315

1416
params: {
1517
apiKey: {

apps/sim/tools/pitchbook/company_industries.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ErrorExtractorId } from '@/tools/error-extractors'
12
import type { PitchbookProfileParams, PitchbookResponse } from '@/tools/pitchbook/types'
23
import { PITCHBOOK_API_BASE, pitchbookAuthHeaders, throwIfNotOk } from '@/tools/pitchbook/utils'
34
import type { ToolConfig } from '@/tools/types'
@@ -9,6 +10,7 @@ export const pitchbookCompanyIndustriesTool: ToolConfig<PitchbookProfileParams,
910
description:
1011
'Retrieve the industry classification, verticals, keywords, and emerging spaces assigned to a company',
1112
version: '1.0.0',
13+
errorExtractor: ErrorExtractorId.PITCHBOOK_ERRORS,
1214

1315
params: {
1416
apiKey: {
@@ -107,16 +109,15 @@ export const pitchbookCompanyIndustriesTool: ToolConfig<PitchbookProfileParams,
107109
description: 'Keywords associated with the company',
108110
items: { type: 'string', description: 'Keyword' },
109111
},
112+
/**
113+
* The recorded sample is an empty array and PitchBook does not publish the
114+
* entry shape anywhere in the collection, so the items stay opaque rather
115+
* than borrowing the sibling `verticals` shape.
116+
*/
110117
emergingSpaces: {
111118
type: 'array',
112119
description: 'Analyst-defined emerging spaces the company is placed in',
113-
items: {
114-
type: 'object',
115-
properties: {
116-
code: { type: 'string', description: 'Emerging space code' },
117-
description: { type: 'string', description: 'Emerging space label' },
118-
},
119-
},
120+
items: { type: 'json' },
120121
},
121122
},
122123
}

apps/sim/tools/pitchbook/company_investors.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ErrorExtractorId } from '@/tools/error-extractors'
12
import type { PitchbookProfileParams, PitchbookResponse } from '@/tools/pitchbook/types'
23
import { PITCHBOOK_API_BASE, pitchbookAuthHeaders, throwIfNotOk } from '@/tools/pitchbook/utils'
34
import type { ToolConfig } from '@/tools/types'
@@ -9,6 +10,7 @@ export const pitchbookCompanyInvestorsTool: ToolConfig<PitchbookProfileParams, P
910
description:
1011
'Retrieve every investor in a company, current and former, with the type of investor and when they invested',
1112
version: '1.0.0',
13+
errorExtractor: ErrorExtractorId.PITCHBOOK_ERRORS,
1214

1315
params: {
1416
apiKey: {

0 commit comments

Comments
 (0)