Skip to content

update is destructive: PATCH replaces config and tools wholesale #14

Description

@chuckmeyer

Established behavior

PATCH /agents/{id} does not merge object fields. Probed on 2026-08-26 with a throwaway draft agent (created, probed, deleted — no existing agent touched), because the OpenAPI spec is reportedly out of sync and the docs don't state the semantics.

Replaced wholesale — anything the payload omits is destroyed:

Field Probe result
config 4 keys → 1; lost enableAlgoliaMcp, feedback, max_iterations
tools array 2 tools → 1; lost algolia_display_results

Preserved even when omitted: index-level enhancedDescription, searchControls, searchParameters; tool-level allowUnlistedIndices, mode.

Why this makes update destructive

cmd_update builds its payload as:

  • "tools": [tool] — a single algolia_search_index, since build_tool() cannot express any other tool type
  • config.get("config") or current.get("config") — the local config block replaces the server's

So algolia-agent update against an agent with a second tool, or with a fuller config than the local file, silently deletes the difference.

This is not hypothetical. Of 14 agents on the account, 7 carry algolia_display_results and all are published. (Corrected from an earlier count of 8-of-9, which was based on a truncated agent list — see #15.) A dry-run against one shows:

  tools:
    - algolia_display_results
  config:
    - enableAlgoliaMcp: True (will be removed)
    - entryPoints: {...} (will be removed)
    - feedback: {"enabled": true} (will be removed)
    - max_iterations: 25 (will be removed)
    - max_tokens: 0 (will be removed)
    - thread_depth: {"max_messages": 0} (will be removed)

Scope

#13 makes this loss visible in --dry-run. It does not prevent it. Preventing it needs a behavior decision:

  1. Merge instead of replace. Start from current and overlay only what the config file specifies, for both config and tools. Preserves unmodeled server state by default; means the CLI can never intentionally remove a tool or config key.
  2. Preserve unrecognized, replace recognized. Carry forward tool types and config keys the CLI has no model for; fully own the ones it does.
  3. Require explicit opt-in to destroy. Keep replace semantics but refuse to send a payload that drops anything unless --allow-remove (or similar) is passed.

Option 3 is probably the smallest safe step, and composes with the dry-run output already in #13.

Related

predefinedSearchParameters (added in #5) appears on zero live agents at tool level, while every index entry carries a field named searchParameters. Possible wrong name/level, i.e. a silent no-op. Worth a separate look.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions