cloudreve/cloudreve · warning
failed to marshal state: %w
Error message
failed to marshal state: %w
What it means
saveState serializes the in-memory State with json.Marshal before writing it to disk. Every State field is a JSON-encodable primitive or map (ints, strings, map[int]bool, map[uint]string), so in the shipped code this error is effectively unreachable: encoding/json only fails on unsupported values such as funcs, channels, complex numbers, NaN floats, or cyclic pointer structures. Encountering it means a custom build added a non-serializable field to State.
Source
Thrown at application/migrator/migrator.go:158
err = model.Init()
if err != nil {
return nil, err
}
v4client, err := inventory.NewRawEntClient(m.l, m.dep.ConfigProvider())
if err != nil {
return nil, err
}
m.v4client = v4client
return m, nil
}
// saveState persists migration state to file
func (m *Migrator) saveState() error {
data, err := json.Marshal(m.state)
if err != nil {
return fmt.Errorf("failed to marshal state: %w", err)
}
return os.WriteFile(m.statePath, data, 0644)
}
// loadState reads migration state from file
func (m *Migrator) loadState() error {
data, err := os.ReadFile(m.statePath)
if err != nil {
return fmt.Errorf("failed to read state file: %w", err)
}
return json.Unmarshal(data, m.state)
}
// updateStep updates current step and persists state
func (m *Migrator) updateStep(step int) error {
m.state.Step = stepView on GitHub (pinned to 20c95ad73f)
Solutions
- Inspect the State struct for func/chan/complex fields or custom MarshalJSON implementations and remove them.
- Keep State limited to plain primitives, strings, slices, and maps of those.
- Add a unit test that round-trips State through json.Marshal/json.Unmarshal to catch regressions in CI.
Defensive patterns
Strategy: validation
Validate before calling
// CI regression guard: State must always be JSON-marshalable.
func TestStateSerializable(t *testing.T) {
s := &State{PolicyIDs: map[int]bool{1: true}, Step: StepGroup}
if _, err := json.Marshal(s); err != nil {
t.Fatalf("State is not serializable: %v", err)
}
} Prevention
- Never add channels, funcs, complex numbers, or cyclic pointers to the persisted State struct.
- Cover State serialization with a unit test in CI.
- Treat any appearance of this error as a signal of a custom patch, not an operational issue.
When it happens
Trigger: A fork or patch adds a field of type func(), chan, or complex128 to State; a float field holds NaN; State references a type whose custom MarshalJSON returns an error.
Common situations: Custom Cloudreve builds; third-party patches that extend the migration State struct without testing persistence.
Related errors
- failed to load migration state: %w
- failed to unmarshal options for group %q: %w
- failed to unmarshal policies for group %q: %w
- failed to update step: %w
- failed to list v3 groups: %w
AI-assisted analysis of cloudreve/cloudreve@20c95ad73f (2026-08-16).
Data as JSON: /api/errors/e37d3fc83ea82306.
Report an issue: GitHub.