restic/restic · error

invalid WriteableFileType

Error message

invalid WriteableFileType

What it means

WriteableFileType is a restricted subset of FileType that lists only repository file types the archiver is allowed to write; today that is exactly one value, WriteableSnapshotFile (= SnapshotFile). ToFileType() maps such a value back to the general FileType. The panic fires when ToFileType() is called on any other value, i.e. a WriteableFileType that was produced by blindly casting an unwritable FileType (data, index, key, lock, config) instead of using the defined constant. It is a compile-time-style type invariant enforced at runtime, not an I/O or environment error.

Source

Thrown at internal/restic/filetype.go:51

		s = "config"
	}
	return s
}

// WriteableFileType defines the different data types that can be modified via SaveUnpacked or RemoveUnpacked.
type WriteableFileType FileType

const (
	// WriteableSnapshotFile is the WriteableFileType for snapshots.
	WriteableSnapshotFile = WriteableFileType(SnapshotFile)
)

func (w *WriteableFileType) ToFileType() FileType {
	switch *w {
	case WriteableSnapshotFile:
		return SnapshotFile
	default:
		panic("invalid WriteableFileType")
	}
}

type FileTypes interface {
	FileType | WriteableFileType
}

View on GitHub (pinned to a80be1478a)

Solutions

  1. Only ever construct WriteableFileType from the defined constant WriteableSnapshotFile; never cast an arbitrary FileType to it
  2. If you are extending restic and genuinely need a new writable type, add both a Writeable* constant and a case in ToFileType() in internal/restic/filetype.go, then run the package tests
  3. Guard before conversion: reject values != WriteableSnapshotFile with a normal error instead of letting the panic fire

Example fix

// before
wft := WriteableFileType(ConfigFile)
ft := wft.ToFileType() // panic: invalid WriteableFileType

// after
wft := WriteableSnapshotFile
ft := wft.ToFileType() // ft == SnapshotFile
Defensive patterns

Strategy: type-guard

Validate before calling

if wft != WriteableSnapshotFile {
    return fmt.Errorf("unsupported writable file type: %v", FileType(wft))
}
ft := wft.ToFileType()

Type guard

func isValidWriteableFileType(w WriteableFileType) bool {
    return w == WriteableSnapshotFile
}

Prevention

When it happens

Trigger: Calling ToFileType() on WriteableFileType(SnapshotFile) succeeds; calling it on a cast of any other FileType (e.g. WriteableFileType(DataFile), WriteableFileType(KeyFile)) panics, as does a zero-value/uninitialized WriteableFileType passed through the conversion. Concretely: wft := WriteableFileType(someFTFromConfig); wft.ToFileType().

Common situations: Forks or PRs of restic that add a new writable file type to the repo layout but forget to add it to the const block and the ToFileType switch; code that accepts a FileType from user input/config and casts it to WriteableFileType without validation; passing a partially-initialized options struct where the field stays zero.

Related errors


AI-assisted analysis of restic/restic@a80be1478a (2026-08-15). Data as JSON: /api/errors/de08728548c2c09f. Report an issue: GitHub.