patch_resource
Make targeted edits to an existing text resource in place — sending only the changes
instead of re-uploading its whole content. This is the practical way to tweak a large
resource: a one-line change stays a one-line request. Address it by its path — set team
for a team resource.
With a credential that represents a user, omitting team targets that user's space. A team must
be bound to the credential and the credential must be allowed to manage it; a userless
organization credential must name such a team.
Only text resources can be edited this way. A binary resource (an image, a PDF, an archive)
must be replaced as a whole with update_resource.
How edits work
You pass an ordered list of edits. Each edit uses exactly one addressing mode:
- Anchored replace — give
old_string(and thenew_stringto put in its place). It must match exactly once; include enough surrounding text to make it unique, or setreplace_allto change every occurrence. - Line-range replace — give
start_lineandend_line(1-based, inclusive). Those lines becomenew_string. - Insertion — give
after_line(1-based; use0to insert at the very top).new_stringis inserted after that line.
Edits apply in order, and each one sees the result of the ones before it. If any edit
fails (for example, its old_string isn't found), none are applied and the resource is
left untouched.
new_string is spliced in verbatim, so include any trailing newline you want. To delete the
matched text or lines, use an empty new_string.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
path | string | Yes | The resource to edit, addressed by its path. |
team | string | No | The team that owns it. Omit to target the represented user's space. |
edits | array | Yes | The edits to apply, in order (see the fields of each edit below). |
expected_version | integer | No | The version you last read. If the resource changed since, the edit is rejected as a conflict instead of overwriting the newer content. |
Each entry in edits:
| Field | Type | Required | Description |
|---|---|---|---|
old_string | string | * | Anchored replace: the exact substring to find (unique unless replace_all is set). |
replace_all | boolean | No | Replace every occurrence of old_string instead of requiring a unique match. |
start_line | integer | * | Line-range replace: first line to replace (1-based, inclusive). Requires end_line. |
end_line | integer | * | Line-range replace: last line to replace (1-based, inclusive). |
after_line | integer | * | Insertion: insert after this line (1-based; 0 = the very top). |
new_string | string | Yes | The replacement/inserted text (verbatim). Empty string to delete the matched text or lines. |
* Provide exactly one of old_string, start_line, or after_line per edit.
Response
| Field | Type | Description |
|---|---|---|
path | string | The resource path. |
id | string | The resource's identifier. |
version | integer | The resource's new version after the edit (pass it back as expected_version on your next edit). |
Example
Bump a version string and append a changelog line:
{
"path": "docs/CHANGELOG.md",
"edits": [
{ "old_string": "version: 1.2.0", "new_string": "version: 1.3.0" },
{ "after_line": 0, "new_string": "## 1.3.0 — latest\n\n" }
]
}
Result:
{
"path": "docs/CHANGELOG.md",
"id": "018f...c2a1",
"version": 4
}
Errors
Each failure carries a precise code in the response. A domain rejection — a not-found, a bad edit, a conflict, a limit, or a permission denial — is returned as a tool result with isError: true, so the agent can read the code and self-correct; malformed arguments and server faults are JSON-RPC protocol errors.
| Code | Cause | Delivered as |
|---|---|---|
resource_not_found | No resource with that path exists in the target space. | tool error (isError) |
not_a_text_resource | The resource is not a text type — replace it with update_resource instead. | tool error (isError) |
invalid_patch | An edit is malformed: its old_string wasn't found or matched more than once without replace_all, its line range or insertion point is out of bounds, or it didn't set exactly one addressing mode. | tool error (isError) |
resource_conflict | The resource changed after the requested version or while the patch was being prepared — re-read and retry. | tool error (isError) |
payload_too_large | The result is larger than your plan's per-file size limit. | tool error (isError) |
storage_limit_reached | The result would exceed your plan's storage limit. | tool error (isError) |
team_not_found | No team with that name is bound to this credential. | tool error (isError) |
forbidden | Your credential isn't permitted to update resources. | tool error (isError) |
personal_cannot_address_team | You used a team/ prefix (or team field) with a personal credential. | tool error (isError) |
no_personal_space | This credential has no personal space — address a team instead. | tool error (isError) |
resource_not_utf8 | The resource is text but its stored bytes aren't valid UTF-8 — edit it in the dashboard. | tool error (isError) |
empty_edits | edits is empty. | tool error (isError) |
invalid_arguments | The arguments are missing or don't match the input schema. | protocol error (invalid_params) |
internal_error | An unexpected error occurred. | protocol error (internal_error) |
Notes
- Editing a resource requires the same permission as
update_resource. - Every content change bumps the resource's
version. To edit safely across steps, read theversion(fromgrep_resourceor a prior edit) and pass it asexpected_version— a concurrent change is then reported as a conflict instead of being silently overwritten. If omitted, the patch starts from the current version and still rejects a change made while it is being prepared. If the original resource is deleted and another is created at the same path, the patch returnsresource_not_foundand leaves the replacement untouched. The patch retains its initial authorization throughout preparation and saving. - The result is bounded by the same per-file and storage limits as any upload — patching does not raise the ceiling; it just spares you from re-sending the whole file.
- Patching a resource counts as one tool call against your plan's tool-invocation allowance.