deepseek-ai/deepseek-harness · error · PresetExistsError

agent-presets: preset "${presetId}" already exists — a copy

Error message

agent-presets: preset "${presetId}" already exists — a copy never overwrites; delete the existing preset first or choose another id

What it means

Error "agent-presets: preset "${presetId}" already exists — a copy never overwrites; delete the existing preset first or choose another id" thrown in deepseek-ai/deepseek-harness.

Source

Thrown at packages/preset/agent-presets/src/index.ts:386

   * Copy is the only authoring write. Composition text never crosses this
   * seam: the source is named by id and its directory is copied as it stands,
   * so the copy is exactly as loadable as its source and authoring grants no
   * capability the roster did not already carry. The copy is NOT mounted to
   * validate — a source that mounts today yields a copy that mounts today.
   * @param from - the preset the copy starts from; shipped presets are the
   * primary source, so any trust is accepted.
   * @param id - the new preset's id, which becomes its directory name.
   * @param name - display name for the copy; absent falls back to the id.
   * @throws when the source is unknown, the id is unusable or already taken,
   * or the deployment configures no writable root.
   */
  async copy(from: string, id: string, name?: string): Promise<void> {
    const source = await this.resolve(from)
    // The roster check refuses ids any root supplies — shipped ones included,
    // since a user directory named like a shipped preset is shadowed by it.
    // The disk check inside copyComposition only sees the writable root.
    if ((await this.list()).some(preset => preset.id === id)) {
      throw new PresetExistsError(id)
    }
    await copyComposition(this.resolvedRoots, source, id, name)
    // A settled mount under this id can only be stale (its preset was deleted
    // from disk outside `remove`); the new preset must not inherit it. Every
    // session already joined keeps the generation it runs on regardless.
    this.standing.delete(id)
  }

  /**
   * Delete a locally authored preset.
   * @param id - the preset id.
   * @throws when the preset is unknown or ships with the deployment.
   */
  async remove(id: string): Promise<void> {
    await deleteComposition(this.resolvedRoots, await this.resolve(id))
    // Sessions on the deleted preset keep their standing mount; only new
    // sessions see the roster without it.
    this.standing.delete(id)

View on GitHub (pinned to b150a551b8)

Solutions

  1. Delete the existing preset first, or choose another id.

When it happens

Trigger: Thrown at packages/preset/agent-presets/src/index.ts:386 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of deepseek-ai/deepseek-harness@b150a551b8 (2026-08-24). Data as JSON: /api/errors/2389c4ecd5814ce5. Report an issue: GitHub.