Repository: ollama/ollama (language: go)

Issue:
client2: pulling non-existent model prints duplicate "not found" error message
### What is the issue?

From @mxyng 

```
$ ollama run nonexistent
pulling manifest
error: model "nonexistent" not found
Error: model 'nonexistent' not found
exit status 1
```

The error gets printed twice.

This is the behavior without the flag:
```
$ ollama run nonexistent
pulling manifest
Error: pull model manifest: file does not exist
exit status 1
```

### OS

Any

### Ollama version

ollama/ollama@1e7f62cb429e5a962dd9c448e7b1b3371879e48b


Discussion / hints:
@mxyng I'm unable to reproduce on `main` at ed4e1393149e1ba5e8fbf5b6629d2658342e39d9. Do you mind trying?
@mxyng Oh! You may have a mixed setup of client and server?
I think I can fix that without muddying things up too much.
@mxyng What is the output of your `ollama --version` when you are able to reproduce this? 

I'm still unable to reproduce with latest ollama client + dev server:

```
; ollama pull llama39
pulling manifest 
error: model "llama39" not found 
; ollama --version
ollama version is 0.0.0
Warning: client version is 0.6.5
```
I cannot reproduce too. Is it possible to close the issue?
Both client and server are on main `56dc316a57f07fbed80723d1ecd589da0906018e`
Still unable to reproduce:

```
OLLAMA_EXPERIMENT=client2 ollama serve
```

```
; git rev-parse HEAD
56dc316a57f07fbed80723d1ecd589da0906018e
; ollama --version
ollama version is 0.0.0
; ollama pull notexist
pulling manifest 
error: model "notexist" not found 
```
I tested in a tight loop to see if it is intermittent, and I am still coming up empty.
Keeping open during alpha testing of client2 in case anyone else is able to reproduce. So far @mxyng and @BruceMacD have be able to do so at fbe70396181222e2d91ca1d8895b11c5fd464c3f.

I am unable to.

Fix patch:
diff --git a/server/internal/registry/server.go b/server/internal/registry/server.go
index bd5f7dcd5b7..af26fe1d5f3 100644
--- a/server/internal/registry/server.go
+++ b/server/internal/registry/server.go
@@ -244,6 +244,7 @@ func (s *Local) handleDelete(_ http.ResponseWriter, r *http.Request) error {
 }
 
 type progressUpdateJSON struct {
+	Error     string      `json:"error,omitempty,omitzero"`
 	Status    string      `json:"status,omitempty,omitzero"`
 	Digest    blob.Digest `json:"digest,omitempty,omitzero"`
 	Total     int64       `json:"total,omitempty,omitzero"`
@@ -348,14 +349,15 @@ func (s *Local) handlePull(w http.ResponseWriter, r *http.Request) error {
 		case err := <-done:
 			flushProgress()
 			if err != nil {
-				var status string
 				if errors.Is(err, ollama.ErrModelNotFound) {
-					status = fmt.Sprintf("error: model %q not found", p.model())
+					return &serverError{
+						Status:  404,
+						Code:    "not_found",
+						Message: fmt.Sprintf("model %q not found", p.model()),
+					}
 				} else {
-					status = fmt.Sprintf("error: %v", err)
+					return err
 				}
-				enc.Encode(progressUpdateJSON{Status: status})
-				return nil
 			}
 
 			// Emulate old client pull progress (for now):


Test patch:
diff --git a/server/internal/registry/server_test.go b/server/internal/registry/server_test.go
index 61b57f11413..15d8d828a04 100644
--- a/server/internal/registry/server_test.go
+++ b/server/internal/registry/server_test.go
@@ -221,7 +221,7 @@ func TestServerPull(t *testing.T) {
 
 	got = s.send(t, "POST", "/api/pull", `{"model": "unknown"}`)
 	checkResponse(got, `
-		{"status":"error: model \"unknown\" not found"}
+		{"code":"not_found","error":"model \"unknown\" not found"}
 	`)
 
 	got = s.send(t, "DELETE", "/api/pull", `{"model": "smol"}`)
@@ -235,7 +235,7 @@ func TestServerPull(t *testing.T) {
 
 	got = s.send(t, "POST", "/api/pull", `{"model": "://"}`)
 	checkResponse(got, `
-		{"status":"error: invalid or missing name: \"\""}
+		{"code":"bad_request","error":"invalid or missing name: \"\""}
 	`)
 
 	// Non-streaming pulls