semaphoreui/semaphore · error

failed to export

Error message

failed to export %s: %s

What it means

The export runner wraps each exporter's load() failure with the failing type name, producing 'failed to export <type>: <cause>'. It is a wrapper error — the root cause is the inner exporter's error (e.g. a DB failure, 'values not loaded', or 'duplicate key').

Solutions

  1. Read the inner error after 'failed to export <type>:' and fix that root cause first
  2. Verify database connectivity and permissions before re-running the export
  3. Re-run the export for the failing type in isolation to reproduce and debug
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: verify store connectivity before export
if err := store.Ping(); err != nil {
    return fmt.Errorf("store unavailable, export will fail: %w", err)
}

Try / catch

err := chain.Export(store)
if err != nil {
    var inner error
    if strings.HasPrefix(err.Error(), "failed to export ") {
        parts := strings.SplitN(err.Error(), ": ", 2)
        inner = errors.New(parts[1]) // root cause
    }
    log.Errorf("export failed: %v (cause: %v)", err, inner)
    return err
}

Prevention

When it happens

Trigger: During Export(), exporter.load(store, p, progress) returns an error for the type `name`; the chain aborts the whole export and returns the wrapped message.

Common situations: Database connectivity problems during export; a type's load hitting 'values not loaded' or 'duplicate key'; permission issues reading from the store mid-export.

Related errors


AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07). Data as JSON: /api/errors/7a50e0a73b98613c. Report an issue: GitHub.

Appendix: source

Thrown at services/export/Exporter.go:495

	if err != nil {
		return
	}

	for _, name := range keys {
		progress := &ProgressBar{printer: func(progress float32, count int64) {
			strLen := len(name)
			spaces := fmt.Sprintf("%*s", 45-strLen, " ")

			fmt.Printf("\rExporting %s%s %d%%", name, spaces, int(progress*100))
		}, progress: 0}

		progress.updateForce(0, 0)
		exporter := p.exporters[name]
		err = exporter.load(store, p, progress)
		if err != nil {
			fmt.Println()
			return fmt.Errorf("failed to export %s: %s", name, err.Error())
		}
		progress.updateForce(1, progress.count)
		fmt.Println()
	}
	return
}

func (p *ExporterChain) Restore(store db.Store, errLogSize int) error {
	keys, err := getSortedKeys(p.exporters, func(t TypeExporter) []string {
		return t.importDependsOn()
	})
	if err != nil {
		return err
	}

	for _, name := range keys {

		progress := &ProgressBar{printer: func(progress float32, count int64) {

View on GitHub (pinned to 1774ccb71a)