Skip to main content

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 the new_string to put in its place). It must match exactly once; include enough surrounding text to make it unique, or set replace_all to change every occurrence.
  • Line-range replace — give start_line and end_line (1-based, inclusive). Those lines become new_string.
  • Insertion — give after_line (1-based; use 0 to insert at the very top). new_string is 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​

ParameterTypeRequiredDescription
pathstringYesThe resource to edit, addressed by its path.
teamstringNoThe team that owns it. Omit to target the represented user's space.
editsarrayYesThe edits to apply, in order (see the fields of each edit below).
expected_versionintegerNoThe 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:

FieldTypeRequiredDescription
old_stringstring*Anchored replace: the exact substring to find (unique unless replace_all is set).
replace_allbooleanNoReplace every occurrence of old_string instead of requiring a unique match.
start_lineinteger*Line-range replace: first line to replace (1-based, inclusive). Requires end_line.
end_lineinteger*Line-range replace: last line to replace (1-based, inclusive).
after_lineinteger*Insertion: insert after this line (1-based; 0 = the very top).
new_stringstringYesThe 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​

FieldTypeDescription
pathstringThe resource path.
idstringThe resource's identifier.
versionintegerThe 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.

CodeCauseDelivered as
resource_not_foundNo resource with that path exists in the target space.tool error (isError)
not_a_text_resourceThe resource is not a text type — replace it with update_resource instead.tool error (isError)
invalid_patchAn 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_conflictThe resource changed after the requested version or while the patch was being prepared — re-read and retry.tool error (isError)
payload_too_largeThe result is larger than your plan's per-file size limit.tool error (isError)
storage_limit_reachedThe result would exceed your plan's storage limit.tool error (isError)
team_not_foundNo team with that name is bound to this credential.tool error (isError)
forbiddenYour credential isn't permitted to update resources.tool error (isError)
personal_cannot_address_teamYou used a team/ prefix (or team field) with a personal credential.tool error (isError)
no_personal_spaceThis credential has no personal space — address a team instead.tool error (isError)
resource_not_utf8The resource is text but its stored bytes aren't valid UTF-8 — edit it in the dashboard.tool error (isError)
empty_editsedits is empty.tool error (isError)
invalid_argumentsThe arguments are missing or don't match the input schema.protocol error (invalid_params)
internal_errorAn 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 the version (from grep_resource or a prior edit) and pass it as expected_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 returns resource_not_found and 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.