# fix(mirror): exit non-zero when create hits an admin-suspended mirror

`60576d5`→[main](/content/gh/entireio/cli/commits/main/index.html)·
toothbrush·2w ago·4 files·+15 added/-10 removed

A suspended mirror can't be used, so `repo mirror create` now fails (exit
non-zero) after printing the warning instead of exiting 0 — a script chaining
a clone shouldn't treat it as success. One-shot returns a SilentError (the
warning is the message); the wizard marks the mirror a failure so the batch
exits non-zero too.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

## Sessions

01bf244ea5d6View transcript

[?\\
Mirror Admin Suspension Warnings and CleanupClaude Code·1 step](/content/gh/entireio/cli/session/8ff7b852-91d4-4bbb-81ad-b152259a2acf#timeline-01bf244ea5d6/index.html)

## Changes

4

- cmd/entire/cli

- Mrepo_mirror.go+4/-1

- Mrepo_mirror_create_wizard.go+3/-3

- Mrepo_mirror_create_wizard_test.go+4/-4

- Mrepo_mirror_test.go+4/-2

```
297 unmodified lines

298
299
300
301
302
303
304
302
305
306
307
308

297 unmodified lines

fmt.Fprintf(out, "  %s\n", created.MirrorUrl)

if created.Suspended {
		// Echo the placement (above), warn, and exit non-zero: the mirror can't
		// be used, so a script chaining a clone shouldn't treat this as success.
		// SilentError keeps main.go from reprinting — the warning is the message.
		fmt.Fprintln(errW, "\nWARNING: this mirror has been suspended by an admin and won't be usable.")
		return nil
		return NewSilentError(errMirrorSuspended)
	}

if !outcome.polled {
```

Mcmd/entire/cli/repo_mirror.go+4/-1

```
516 unmodified lines

517
518
519
520
521
522
520
521
522
523
524
525

516 unmodified lines

if outcome.created.Suspended {
		// An admin suspended this existing placement, so it won't be served.
		// Surface it as a distinct status rather than a bare "registered"; it is
		// non-fatal (no res.err), matching the one-shot's warning semantics.
		res.status = mirrorStatusSuspended
		// Surface it as a distinct status and set an error so the batch exits
		// non-zero, matching the one-shot: a suspended mirror isn't a success.
		res.status, res.err = mirrorStatusSuspended, errors.New("suspended by an admin; won't be usable")
		report(mirrorStatusSuspended, true, false)
		return res
	}
```

Mcmd/entire/cli/repo_mirror_create_wizard.go+3/-3

```
12 unmodified lines

13
14
15
16
17
18
16
17
18
19
20
21
12 unmodified lines

34
35
36
37
37
38
39
40

12 unmodified lines

)// TestCreateOneMirror_Suspended pins the wizard's per-mirror handling of an
// admin-suspended existing placement: it surfaces the "suspended" status and,
// like the one-shot warning, stays non-fatal (no res.err) rather than being
// reported as a plain "registered" success or a hard failure.
// admin-suspended existing placement: it surfaces the "suspended" status and
// sets an error so the batch exits non-zero (matching the one-shot), rather
// than being reported as a plain "registered" success.
func TestCreateOneMirror_Suspended(t *testing.T) {

t.Parallel()

12 unmodified lines

})

require.Equal(t, mirrorStatusSuspended, res.status)
require.NoError(t, res.err, "a suspended placement is non-fatal in the wizard too")
require.Error(t, res.err, "a suspended placement must fail the batch (non-zero exit)")
require.Equal(t, mirrorStatusSuspended, final)
require.False(t, finalOK)
require.Equal(t, []string{mirrorsAPIPath}, *paths, "suspended must not poll GetMirror")
```

Mcmd/entire/cli/repo_mirror_create_wizard_test.go+4/-4

```
295 unmodified lines

296
297
298
299
299
300
301
302
303
304
304
305
306
307
308
309

295 unmodified lines

require.NotContains(t, out.String(), "git clone")
	})

t.Run("suspended placement warns after the placement and succeeds", func(t *testing.T) {
t.Run("suspended placement warns after the placement and exits non-zero", func(t *testing.T) {
					
t.Parallel()
		var out, errW bytes.Buffer
		created := &coreapi.CreatedMirror{Created: false, MirrorId: id, MirrorUrl: mirrorURL, Suspended: true}
		err := reportOneShotMirror(&out, &errW, mirrorCreateOutcome{created: created}, nil)
		require.NoError(t, err, "a suspended re-create is a non-fatal warning")
		var silent *SilentError
		require.ErrorAs(t, err, &silent, "a suspended re-create must exit non-zero")
		require.ErrorIs(t, err, errMirrorSuspended)
		require.Contains(t, out.String(), "Mirror exists ("+id, "the placement is still echoed")
		require.Contains(t, errW.String(), "WARNING: this mirror has been suspended by an admin and won't be usable.")
		require.NotContains(t, out.String(), "git clone")
```

Mcmd/entire/cli/repo_mirror_test.go+4/-2

```
