<!-- Generated by crates/swarmops-cli/src/reference.rs from the code: do not edit. Change the code, then run SWARMOPS_REGEN_REFERENCE=1 with the regen_reference test. -->

# swarmops blob has

Of the IDs given, list those the store holds blobs under.

```yaml
title: "swarmops blob has"
description: "Of the IDs given, list those the store holds blobs under."
group: "write"
since: "0.1.0"
mutates: false
identity_required: false
mcp_tool: "blob_has"
envelope_op: "blob_has"
exit_codes: [0]
errors: []
syntax: "swarmops blob has [OPTIONS] <ID>..."
```

## Syntax

```text
swarmops blob has [OPTIONS] <ID>...
```

## Required arguments

### `ID`

Syntax: `<ID>`.

Blob ids, 64 hex digits each.

## Optional arguments

The command also takes the [global options](../cli.md#global-options).

## Examples

### CLI

```sh
swarmops --repo [tmp]/store blob has [blob] [missing]
```

```json
{
  "ok": true,
  "op": "blob_has",
  "api": 1,
  "result": {
    "present": [
      "[blob]"
    ]
  },
  "meta": {
    "repo": "[tmp]/store",
    "elapsed_ms": "[elapsed_ms]",
    "resolved": {},
    "auth": "trust"
  }
}
```

Exit code 0. Recorded by the CLI tests. A name in square brackets, such as `[tmp]` or `[c1]`, stands for what differs from run to run: the test's temporary directory, an id, a time.

### MCP

No recorded example yet.

## Details

`blob has` asks which of some blob ids the store holds, without reading any of their bytes. It
reads only: it needs no identity and writes nothing. Its MCP tool is `blob_has`, which takes the
ids as an array.

### Behaviour

- Each ID is a blob id in full, 64 hex digits, of either case. A prefix is not taken: only a
  revision resolves a prefix of a changeset id.
- Every ID is checked before the store is asked about any. One that is not 64 hex digits fails
  the whole command with `E_INVALID_ARG` (exit 2), `details.index` (from 0) and `details.blob`
  naming it.
- `present` lists the IDs the store holds a blob under, in lowercase, in the order first given,
  each once however often it was given. An ID the store does not hold is simply absent: a
  missing blob is not an error.
- An ID of another kind of object, a changeset or a tree, is never present, since it names no
  blob.
- It reads each object's header alone, so a blob listed as present has not had its bytes
  checked; [`verify --deep`](../commands/verify.md) checks them.

### Patterns

- Before a commit that names blobs by id, check them: a change whose `blob` the store does not
  hold fails the commit with `E_INVALID_ARG`, naming the change, and records nothing.
- Before putting a large file, ask whether its id is there already, when you have the id from
  an earlier [`blob put`](../commands/blob-put.md) or from a changeset's change list
  ([`show`](../commands/show.md)).
- Compare the result with what you asked to find the missing ones: the ids you gave, lowercased,
  less `present`.

## Return information

`result` is a `BlobHasResp` (`swarmops schema BlobHasResp` prints its JSON Schema).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `present` | `array of string` | yes | The ids of `ids` that the store holds a blob under, in lowercase hex, in the order first given, each once; an id of another kind of object (a tree, a changeset) is not among them. |

Envelope `op`: `blob_has`.

Exit codes:

- `0`: Success.

## Errors

No golden step shows this command failing yet.

Any command that opens a store may also fail with a store error, such as [`E_NOT_A_REPO`](../errors.md#e_not_a_repo), [`E_IO`](../errors.md#e_io) or [`E_STORE_CORRUPT`](../errors.md#e_store_corrupt); a command line the grammar refuses is [`E_INVALID_ARG`](../errors.md#e_invalid_arg) (exit 2).

## See also

- [`swarmops commit`](commit.md)
- [`swarmops land`](land.md)
- [`swarmops blob put`](blob-put.md)
- [CLI reference](../cli.md)
- [Error codes](../errors.md)
