Skip to content

Commit 51d2118

Browse files
feat(tools): run one integration tool over v2, and fix the ones that could not be run (#7374)
* feat(tools): run one integration tool over v2, and fix the ones that could not be run Adds `POST /api/v2/tools/{toolId}/execute` and `sim tools execute <toolId>`, then fixes the 119 tool parameters that made the same call impossible through Copilot. The catalog already published every tool's parameters and outputs; there was no way to supply them. The only execution endpoint on v2 was `POST /workflows/{id}/execute`, so a caller could read that `gmail_send` takes `{to, subject, body}` and still had to wrap it in a workflow to send the mail. Building it surfaced the second half. Copilot authorizes integration tools when their schemas are built — `projectIntegrationToolsForViewer` decides what the model is told exists — so by dispatch the id has been vouched for. An endpoint whose caller types the id has to make those decisions against it, which is what the use case does, and which is how the parameters below came to light. 117 of them are mislabels: mailchimp and zendesk mark a user-typed API key `hidden`, which firecrawl spells `user-only` for the identical shape, and pipedrive and wealthbox omit the `oauth` declaration that fills the `accessToken` they correctly hide. The other 2 are not — calcom's `attendee` and mistral's `file` are composed by their block at serialization time, so `hidden` was right until a caller could reach the tool directly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(mistral): align MistralParseV3Block on the tool's `file` parameter `check-block-registry.ts` requires every required `user-only` tool parameter to have a subBlock whose `id` or `canonicalParamId` matches it, because the serializer resolves those by direct lookup and a mismatch false-flags the field as missing at submit time. V3's subBlocks carried `canonicalParamId: 'document'` against a tool parameter named `file`, bridged by the block's params mapper. Aligning them needs no migration. Saved state is keyed by subBlock id (`fileUpload`, `fileReference`), which is unchanged; `canonicalParamId` is a config-derived index rather than a storage key. `data.canonicalModes` is keyed by canonical id, but `backfillCanonicalModes` re-derives a missing entry from whichever value is populated, so a workflow using the advanced file-reference field still resolves to `advanced` on open. V2 keeps `document`: only V3's `file` parameter is `required`, so only V3 is under the contract. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(tools): reject a direct call missing a required user-only input `validateRequiredParametersAfterMerge` checks `user-or-llm` parameters alone, because on the workflow path a `user-only` parameter was already validated during serialization against the block field that holds it. The v2 execute path has no serialization step, so nothing had checked them: omitting `zendesk_get_ticket`'s `subdomain` reached Zendesk as `undefined` and came back a provider authentication failure — the same undiagnosable shape this branch set out to remove. The check exempts a parameter Sim supplies itself, mirroring `injectHostedKeyIfNeeded`'s three tests in the same order so the two cannot disagree about whether a value is coming. `firecrawl_scrape` stays callable with no `apiKey` where keys are hosted, and requires one where they are not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(tools): require every input the caller is the only source for The previous commit gated the check on `user-only`, which reads the visibility taxonomy as if it constrained who may send a value. It does not. `visibility` describes editor roles — a human filling a block field, the agent block's model choosing an argument, either, or neither — and a direct call has no editor and no agent block, so those roles collapse to one caller. `createUserToolSchema`, which this endpoint and Copilot's `call_integration_tool` both publish, already says so by omitting `hidden` and nothing else. So the rule is not about roles: Sim supplies it, or the caller must. Skipping `hidden` stays safe because `check-tool-param-reachability` fails any required hidden parameter without a declared filler. Concretely this closes `thinking_tool.thought`, the one required `llm-only` parameter in the registry, which the narrower check let through as `undefined`. It also moves required `user-or-llm` inputs to a pre-dispatch failure naming every missing field at once, rather than the merge validator's first-failure mid-execution. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(tools): address the cubic review round on direct tool execution Two were real defects rather than polish: The usage ledger de-duplicates on `eventKey`, and the derived key hashes actor, workspace, source and description — identical for every call to the same tool. `onConflictDoNothing` therefore billed the first hosted-key call and silently dropped every one after it. A workflow run has an `executionId` to separate its rows; a direct call has nothing, so it now mints one. Undeclared input keys reached the executor. `impersonateUserEmail` is read straight out of params and forwarded to credential-token resolution as an impersonation request, and no tool declares it. The two ad-hoc denylists are replaced by a declared-parameter allowlist — the actual boundary, and the one `GET /api/v2/tools/{toolId}` already publishes. Also: renaming a canonical id orphans `data.canonicalModes`, and the backfill recovers it only when one side holds a value. `setBlockCanonicalMode` writes the mode without clearing its sibling, so a workflow holding both would have silently switched from the typed reference to the uploaded file. `migrateCanonicalModeIds` carries the key across, ahead of the backfill. Smaller: the reachability audit now mirrors execution exactly, exempting `credentialType` only under `authoritativeParams` and refusing to treat conditional hosting as a guarantee; the boundary guard splits on both path separators so it still excludes the execute route on Windows; the route stops documenting the 409 and 423 it cannot produce; and `sim tools execute` prints the output it promised in the human formats. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(tools): bill only spend that was Sim's, and scope the boundary predicate Metering read `output.cost.total` and billed it. That field is not a hosted-key marker: `knowledge_upload_chunk` and the enrichment runner report their own cost there, so a workspace would have been charged `api-tool` spend for something already metered elsewhere, and a failed call carrying a cost billed too. The registry writes hosted-key cost under exactly two conditions — `hostedKeyInfo.isUsingHostedKey && finalResult.success` — and metering now matches them. `hostedKeyParamFor` derives the first of those the way `injectHostedKeyIfNeeded` does, including the test the earlier version omitted: a caller's own key wins, so supplying one means Sim's key was never spent. The same helper answers the other question that turns on it, since a required parameter Sim fills is not a missing one. The boundary predicate matched `execute` anywhere in the absolute path, so a checkout living under a directory of that name would have excluded every catalog route and retired the guard silently. Now derived from the path relative to the app, still split on either separator for Windows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(tools): refuse a caller-supplied hidden parameter Declared was being treated as accepted. A `hidden` parameter is Sim's to fill — a resolved credential's `accessToken`, a hosted key, a block-composed shape — and `createUserToolSchema` omits it from what this endpoint and Copilot publish. Accepting it anyway either let a caller pre-empt the executor's value or silently discarded theirs when the executor overwrote it; either way the published schema made no such promise. The accept-set is now exactly the publish-set: a key is taken if and only if `GET /api/v2/tools/{toolId}` lists it as something the caller may send. This is the rule the required-input check already followed ("Sim fills it, or the caller must"), applied to the other direction. Verified live against a dev server: a forged `accessToken` on `gmail_read_v2` is refused before dispatch, and the credential-backed read still succeeds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(tools): honor a tool's declared credential selector, and refuse its aliases first Sixty-eight tools — Snowflake among them — declare the credential selector as a required `user-only` parameter (`oauthCredential` or `credential`) with no `oauth` block, filled by their block from an `oauth-input` field. The required-input check ran against the raw body, before the top-level `credentialId` had been placed anywhere, so a valid credential was rejected as a missing `oauthCredential`. And the alias refusal ran only over *undeclared* keys, so `input.oauthCredential` on such a tool passed the declared-key check and bypassed the top-level field — credential precedence differing per tool. The credential is still named once, at the top level. It now lands under whichever selector the tool declares (or `credential`, which the executor reads for OAuth resolution, when it declares none), and required inputs are validated against what the executor will actually receive. A declared required selector also demands `credentialId` up front, the same as an `oauth` block does. The alias refusal is unconditional and runs first. Verified live: a Snowflake call with a top-level credential passes the validator and fails downstream at resolution; `input.oauthCredential` is refused; omitting the credential names `credentialId` as required. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(tools): read the registry's hosted-key verdict instead of re-deriving it The metering gate re-derived "did Sim's key pay" from the tool's hosting config and whether the caller omitted the key. That cannot see a workspace or organization BYOK key, which `injectHostedKeyIfNeeded` injects while reporting `isUsingHostedKey: false` — the org's own key, not billable — so the derivation called a BYOK call hosted. The registry's verdict does propagate, by one path. On a tool with `hosting`, `output.cost` has a single writer, `applyHostedKeyCostToResult`, and it runs only under `isUsingHostedKey && success`. A BYOK call, a caller-keyed call, and a failed call all leave the field absent. The gate now reads that: `hosting` present, success, cost present. The derivation stays for the one question it can answer before dispatch — a parameter Sim will fill is not missing. The reading rests on hosted tools not reporting their own cost in that field, which is true of all 131 today and now pinned by the reachability audit, so a future hosted tool that self-reports fails CI rather than billing BYOK calls. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(audit): exempt a token-response field only where the tool declares it The reachability audit treated seven credential-derived fields as guaranteed fillers for a required hidden parameter on any OAuth tool. Only `accessToken` is: the resolver assigns it unconditionally. `idToken`, `instanceUrl`, `apiDomain`, `cloudId`, `domain` and `authStyle` are assigned under `if (data.X)` — present on some providers' credentials and absent on others — and `credentialType` additionally only when the tool lists it in `authoritativeParams`. Whether a credential carries one is a fact about the provider that the resolver cannot vouch for. The tool can. `oauth.authoritativeParams` is already the declaration that the token response supplies the named field, and every real case — the eight `microsoft_dynamics_365_*` tools hiding `instanceUrl` — already lists it. So a required hidden parameter in that set is now exempt only when its tool declares it there, generalising the rule `credentialType` alone had. A tool that hides one without declaring it is asserting a filler the resolver may never run, which is the shape this audit exists to reject. Mutation-tested at the real declaration site: stripping `authoritativeParams` from `DYNAMICS_365_OAUTH_CONFIG` fails the audit naming all eight tools with the remedy; restoring passes. Nothing is flagged on the current tree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 452e542 commit 51d2118

159 files changed

Lines changed: 23402 additions & 166 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/cli/billing.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ List credit usage events (a personal API key reports only your own events; a wor
3939

4040
| Option | Required | Description |
4141
| --- | --- | --- |
42-
| `--source <value>` | No | Filter by usage source; sim-chat combines Copilot and workspace chat. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`. |
42+
| `--source <value>` | No | Filter by usage source; sim-chat combines Copilot and workspace chat. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`, `api-tool`. |
4343
| `--period <value>` | No | Billing period. Accepted values: `1d`, `7d`, `30d`, `all`, `custom`. |
4444
| `--start-date <value>` | No | Custom period start (ISO 8601). |
4545
| `--end-date <value>` | No | Custom period end (ISO 8601). |

apps/docs/content/docs/cli/reference.mdx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ sim billing logs [options]
263263

264264
| Option | Required | Description |
265265
| --- | --- | --- |
266-
| `--source <value>` | No | Filter by usage source; sim-chat combines Copilot and workspace chat. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`. |
266+
| `--source <value>` | No | Filter by usage source; sim-chat combines Copilot and workspace chat. Accepted values: `workflow`, `wand`, `sim-chat`, `mcp_copilot`, `mothership_block`, `knowledge-base`, `voice-input`, `enrichment`, `voice-output`, `api-tool`. |
267267
| `--period <value>` | No | Billing period. Accepted values: `1d`, `7d`, `30d`, `all`, `custom`. |
268268
| `--start-date <value>` | No | Custom period start (ISO 8601). |
269269
| `--end-date <value>` | No | Custom period end (ISO 8601). |
@@ -4366,6 +4366,36 @@ sim tables mkdir <path>
43664366

43674367
## sim tools
43684368

4369+
### sim tools execute
4370+
4371+
Run one built-in tool and print what it produced (personal API key required)
4372+
4373+
```bash
4374+
sim tools execute <toolId> [options]
4375+
```
4376+
4377+
**Arguments**
4378+
4379+
<CommandTable>
4380+
4381+
| Argument | Required | Description |
4382+
| --- | --- | --- |
4383+
| `toolId` | Yes | Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id. |
4384+
4385+
</CommandTable>
4386+
4387+
**Options**
4388+
4389+
<CommandTable>
4390+
4391+
| Option | Required | Description |
4392+
| --- | --- | --- |
4393+
| `--input <json\|@file>` | No | Tool arguments as JSON, keyed by the parameter ids `sim tools get &lt;toolId&gt;` lists (JSON, or @path / @- to read a file or stdin). |
4394+
| `--credential-id <value>` | No | Credential to authenticate with, required for OAuth tools. |
4395+
| `--timeout <value>` | No | Seconds to wait before abandoning the call. |
4396+
4397+
</CommandTable>
4398+
43694399
### sim tools get
43704400

43714401
Get Tool

apps/docs/content/docs/cli/tools.mdx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,36 @@ import { CommandTable } from '@/components/ui/command-table'
77

88
Every command below also accepts the [global options](/cli/commands#global-options).
99

10+
## Run one built-in tool and print what it produced
11+
12+
```bash
13+
sim tools execute <toolId> [options]
14+
```
15+
16+
Run one built-in tool and print what it produced (personal API key required)
17+
18+
**Arguments**
19+
20+
<CommandTable>
21+
22+
| Argument | Required | Description |
23+
| --- | --- | --- |
24+
| `toolId` | Yes | Tool identifier. An unversioned name resolves to the newest version, and the response echoes the resolved id. |
25+
26+
</CommandTable>
27+
28+
**Options**
29+
30+
<CommandTable>
31+
32+
| Option | Required | Description |
33+
| --- | --- | --- |
34+
| `--input <json\|@file>` | No | Tool arguments as JSON, keyed by the parameter ids `sim tools get &lt;toolId&gt;` lists (JSON, or @path / @- to read a file or stdin). |
35+
| `--credential-id <value>` | No | Credential to authenticate with, required for OAuth tools. |
36+
| `--timeout <value>` | No | Seconds to wait before abandoning the call. |
37+
38+
</CommandTable>
39+
1040
## Get tool
1141

1242
```bash

apps/docs/content/docs/integrations/calcom.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Create a new booking on Cal.com
4444
| --------- | ---- | -------- | ----------- |
4545
| `eventTypeId` | number | Yes | The ID of the event type to book |
4646
| `start` | string | Yes | Start time in UTC ISO 8601 format \(e.g., 2024-01-15T09:00:00Z\) |
47-
| `attendee` | object | Yes | Attendee information object with name, email, timeZone, and optional phoneNumber \(constructed from individual attendee fields\) |
47+
| `attendee` | object | Yes | Attendee information object with name, email, timeZone, and optional phoneNumber. The Cal.com block composes this from its individual attendee fields; a direct caller sends the object. |
4848
| `guests` | array | No | Array of guest email addresses |
4949
| `lengthInMinutes` | number | No | Duration of the booking in minutes \(overrides event type default\) |
5050
| `metadata` | object | No | Custom metadata to attach to the booking |

apps/docs/openapi-v2-billing.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@
122122
"knowledge-base",
123123
"voice-input",
124124
"enrichment",
125-
"voice-output"
125+
"voice-output",
126+
"api-tool"
126127
]
127128
}
128129
},
@@ -452,7 +453,7 @@
452453
"description": "Human-readable explanation of the error."
453454
},
454455
"details": {
455-
"description": "Structured error details. On a `403` whose cause a caller can act on, this carries a `code` from a closed set:\n- `INSUFFICIENT_WORKSPACE_ROLE` — The caller has access to the workspace but its role is below the one this operation requires.\n- `PERSONAL_API_KEYS_DISABLED` — The workspace's organization does not allow personal API keys. Use a workspace API key.\n- `WORKSPACE_KEY_OPERATION_NOT_PERMITTED` — This operation is not available to a workspace-scoped API key. Use a personal API key.\n- `PRINCIPAL_KIND_NOT_PERMITTED` — This operation does not accept the caller’s kind of API key.\n- `ORGANIZATION_MEMBERSHIP_REQUIRED` — The caller is not a member of the organization it named.\n- `ORGANIZATION_ADMIN_REQUIRED` — The caller is a member of the organization but not an admin or owner.\n- `ENTERPRISE_PLAN_REQUIRED` — The organization has no active enterprise subscription.\n- `ORGANIZATION_PLAN_REQUIRED` — The organization has no active organization subscription (Pro for Teams, Max for Teams, or Enterprise).\n- `AUDIT_LOGS_DISABLED` — Audit logging is not enabled for this deployment.\n- `SKILL_EDITOR_ACCESS_REQUIRED` — The caller can write in the workspace but is not an editor of this skill.\n- `SECRET_ADMIN_ACCESS_REQUIRED` — The caller can write in the workspace but is not an admin of this secret. Ask a workspace admin, or someone holding admin on the secret, to grant access or set the value.\n- `WORKSPACE_RESOURCE_LIMIT_REACHED` — The workspace already holds the maximum number of resources of this kind. Delete one, or contact Sim to raise the limit; the message names the ceiling.\n- `PUBLIC_SHARING_NOT_ALLOWED` — The workspace's organization does not permit sharing this resource publicly. An organization admin controls the policy.\n- `CREDENTIAL_ADMIN_ACCESS_REQUIRED` — The caller can reach the workspace but cannot administer this credential.\n- `MCP_SERVER_URL_NOT_ALLOWED` — The supplied MCP server URL is outside the allowed domains or resolves to an internal address.\n- `WORKSPACE_PLAN_CAPABILITY_REQUIRED` — The workspace's plan does not include a capability this request depends on. The message names the capability; upgrading the workspace's plan is the remedy.\n- `CHAT_AUTH_MODE_NOT_PERMITTED` — The workspace's permission group does not allow the chat authentication mode the request selected. A mode already saved on the deployment may still be re-saved; changing to a disallowed one cannot.\n- `CONNECTOR_MANAGED_RESOURCE_READ_ONLY` — This resource is managed by a knowledge base connector and cannot be edited directly. Change it at the source and re-sync, or exclude the document from the connector.\n- `PERMISSION_GROUP_CAPABILITY_BLOCKED` — The caller's permission group does not allow this capability. The message names it; an organization admin controls the group."
456+
"description": "Structured error details. On a `403` whose cause a caller can act on, this carries a `code` from a closed set:\n- `INSUFFICIENT_WORKSPACE_ROLE` — The caller has access to the workspace but its role is below the one this operation requires.\n- `PERSONAL_API_KEYS_DISABLED` — The workspace's organization does not allow personal API keys. Use a workspace API key.\n- `WORKSPACE_KEY_OPERATION_NOT_PERMITTED` — This operation is not available to a workspace-scoped API key. Use a personal API key.\n- `PRINCIPAL_KIND_NOT_PERMITTED` — This operation does not accept the caller’s kind of API key.\n- `ORGANIZATION_MEMBERSHIP_REQUIRED` — The caller is not a member of the organization it named.\n- `ORGANIZATION_ADMIN_REQUIRED` — The caller is a member of the organization but not an admin or owner.\n- `ENTERPRISE_PLAN_REQUIRED` — The organization has no active enterprise subscription.\n- `ORGANIZATION_PLAN_REQUIRED` — The organization has no active organization subscription (Pro for Teams, Max for Teams, or Enterprise).\n- `AUDIT_LOGS_DISABLED` — Audit logging is not enabled for this deployment.\n- `SKILL_EDITOR_ACCESS_REQUIRED` — The caller can write in the workspace but is not an editor of this skill.\n- `SECRET_ADMIN_ACCESS_REQUIRED` — The caller can write in the workspace but is not an admin of this secret. Ask a workspace admin, or someone holding admin on the secret, to grant access or set the value.\n- `WORKSPACE_RESOURCE_LIMIT_REACHED` — The workspace already holds the maximum number of resources of this kind. Delete one, or contact Sim to raise the limit; the message names the ceiling.\n- `PUBLIC_SHARING_NOT_ALLOWED` — The workspace's organization does not permit sharing this resource publicly. An organization admin controls the policy.\n- `CREDENTIAL_ADMIN_ACCESS_REQUIRED` — The caller can reach the workspace but cannot administer this credential.\n- `MCP_SERVER_URL_NOT_ALLOWED` — The supplied MCP server URL is outside the allowed domains or resolves to an internal address.\n- `WORKSPACE_PLAN_CAPABILITY_REQUIRED` — The workspace's plan does not include a capability this request depends on. The message names the capability; upgrading the workspace's plan is the remedy.\n- `CHAT_AUTH_MODE_NOT_PERMITTED` — The workspace's permission group does not allow the chat authentication mode the request selected. A mode already saved on the deployment may still be re-saved; changing to a disallowed one cannot.\n- `CONNECTOR_MANAGED_RESOURCE_READ_ONLY` — This resource is managed by a knowledge base connector and cannot be edited directly. Change it at the source and re-sync, or exclude the document from the connector.\n- `PERMISSION_GROUP_CAPABILITY_BLOCKED` — The caller's permission group does not allow this capability. The message names it; an organization admin controls the group.\n- `INTEGRATION_NOT_ALLOWED` — The integration this request names is outside the workspace's allowed set. An organization admin controls the permission group's integration allowlist, and a self-hosted deployment can narrow it further with ALLOWED_INTEGRATIONS."
456457
}
457458
},
458459
"required": ["code", "message"],
@@ -636,7 +637,8 @@
636637
"knowledge-base",
637638
"voice-input",
638639
"enrichment",
639-
"voice-output"
640+
"voice-output",
641+
"api-tool"
640642
],
641643
"description": "Product surface that consumed the credits."
642644
},

apps/docs/openapi-v2-files-audit.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2793,7 +2793,7 @@
27932793
"description": "Human-readable explanation of the error."
27942794
},
27952795
"details": {
2796-
"description": "Structured error details. On a `403` whose cause a caller can act on, this carries a `code` from a closed set:\n- `INSUFFICIENT_WORKSPACE_ROLE` — The caller has access to the workspace but its role is below the one this operation requires.\n- `PERSONAL_API_KEYS_DISABLED` — The workspace's organization does not allow personal API keys. Use a workspace API key.\n- `WORKSPACE_KEY_OPERATION_NOT_PERMITTED` — This operation is not available to a workspace-scoped API key. Use a personal API key.\n- `PRINCIPAL_KIND_NOT_PERMITTED` — This operation does not accept the caller’s kind of API key.\n- `ORGANIZATION_MEMBERSHIP_REQUIRED` — The caller is not a member of the organization it named.\n- `ORGANIZATION_ADMIN_REQUIRED` — The caller is a member of the organization but not an admin or owner.\n- `ENTERPRISE_PLAN_REQUIRED` — The organization has no active enterprise subscription.\n- `ORGANIZATION_PLAN_REQUIRED` — The organization has no active organization subscription (Pro for Teams, Max for Teams, or Enterprise).\n- `AUDIT_LOGS_DISABLED` — Audit logging is not enabled for this deployment.\n- `SKILL_EDITOR_ACCESS_REQUIRED` — The caller can write in the workspace but is not an editor of this skill.\n- `SECRET_ADMIN_ACCESS_REQUIRED` — The caller can write in the workspace but is not an admin of this secret. Ask a workspace admin, or someone holding admin on the secret, to grant access or set the value.\n- `WORKSPACE_RESOURCE_LIMIT_REACHED` — The workspace already holds the maximum number of resources of this kind. Delete one, or contact Sim to raise the limit; the message names the ceiling.\n- `PUBLIC_SHARING_NOT_ALLOWED` — The workspace's organization does not permit sharing this resource publicly. An organization admin controls the policy.\n- `CREDENTIAL_ADMIN_ACCESS_REQUIRED` — The caller can reach the workspace but cannot administer this credential.\n- `MCP_SERVER_URL_NOT_ALLOWED` — The supplied MCP server URL is outside the allowed domains or resolves to an internal address.\n- `WORKSPACE_PLAN_CAPABILITY_REQUIRED` — The workspace's plan does not include a capability this request depends on. The message names the capability; upgrading the workspace's plan is the remedy.\n- `CHAT_AUTH_MODE_NOT_PERMITTED` — The workspace's permission group does not allow the chat authentication mode the request selected. A mode already saved on the deployment may still be re-saved; changing to a disallowed one cannot.\n- `CONNECTOR_MANAGED_RESOURCE_READ_ONLY` — This resource is managed by a knowledge base connector and cannot be edited directly. Change it at the source and re-sync, or exclude the document from the connector.\n- `PERMISSION_GROUP_CAPABILITY_BLOCKED` — The caller's permission group does not allow this capability. The message names it; an organization admin controls the group."
2796+
"description": "Structured error details. On a `403` whose cause a caller can act on, this carries a `code` from a closed set:\n- `INSUFFICIENT_WORKSPACE_ROLE` — The caller has access to the workspace but its role is below the one this operation requires.\n- `PERSONAL_API_KEYS_DISABLED` — The workspace's organization does not allow personal API keys. Use a workspace API key.\n- `WORKSPACE_KEY_OPERATION_NOT_PERMITTED` — This operation is not available to a workspace-scoped API key. Use a personal API key.\n- `PRINCIPAL_KIND_NOT_PERMITTED` — This operation does not accept the caller’s kind of API key.\n- `ORGANIZATION_MEMBERSHIP_REQUIRED` — The caller is not a member of the organization it named.\n- `ORGANIZATION_ADMIN_REQUIRED` — The caller is a member of the organization but not an admin or owner.\n- `ENTERPRISE_PLAN_REQUIRED` — The organization has no active enterprise subscription.\n- `ORGANIZATION_PLAN_REQUIRED` — The organization has no active organization subscription (Pro for Teams, Max for Teams, or Enterprise).\n- `AUDIT_LOGS_DISABLED` — Audit logging is not enabled for this deployment.\n- `SKILL_EDITOR_ACCESS_REQUIRED` — The caller can write in the workspace but is not an editor of this skill.\n- `SECRET_ADMIN_ACCESS_REQUIRED` — The caller can write in the workspace but is not an admin of this secret. Ask a workspace admin, or someone holding admin on the secret, to grant access or set the value.\n- `WORKSPACE_RESOURCE_LIMIT_REACHED` — The workspace already holds the maximum number of resources of this kind. Delete one, or contact Sim to raise the limit; the message names the ceiling.\n- `PUBLIC_SHARING_NOT_ALLOWED` — The workspace's organization does not permit sharing this resource publicly. An organization admin controls the policy.\n- `CREDENTIAL_ADMIN_ACCESS_REQUIRED` — The caller can reach the workspace but cannot administer this credential.\n- `MCP_SERVER_URL_NOT_ALLOWED` — The supplied MCP server URL is outside the allowed domains or resolves to an internal address.\n- `WORKSPACE_PLAN_CAPABILITY_REQUIRED` — The workspace's plan does not include a capability this request depends on. The message names the capability; upgrading the workspace's plan is the remedy.\n- `CHAT_AUTH_MODE_NOT_PERMITTED` — The workspace's permission group does not allow the chat authentication mode the request selected. A mode already saved on the deployment may still be re-saved; changing to a disallowed one cannot.\n- `CONNECTOR_MANAGED_RESOURCE_READ_ONLY` — This resource is managed by a knowledge base connector and cannot be edited directly. Change it at the source and re-sync, or exclude the document from the connector.\n- `PERMISSION_GROUP_CAPABILITY_BLOCKED` — The caller's permission group does not allow this capability. The message names it; an organization admin controls the group.\n- `INTEGRATION_NOT_ALLOWED` — The integration this request names is outside the workspace's allowed set. An organization admin controls the permission group's integration allowlist, and a self-hosted deployment can narrow it further with ALLOWED_INTEGRATIONS."
27972797
}
27982798
},
27992799
"required": ["code", "message"],

0 commit comments

Comments
 (0)