plandex-ai/plandex · error

error unmarshalling apply file: %v

Error message

error unmarshalling apply file: %v

What it means

An apply file was read successfully but json.Unmarshal into PlanApply failed. This means at least one *.json file in the applies directory is not valid PlanApply JSON — corrupt, truncated, empty, or written by an incompatible schema version.

Source

Thrown at app/server/db/result_helpers.go:1066

			defer func() {
				if r := recover(); r != nil {
					log.Printf("panic in GetPlanApplies: %v\n%s", r, debug.Stack())
					errCh <- fmt.Errorf("panic in GetPlanApplies: %v\n%s", r, debug.Stack())
					runtime.Goexit() // don't allow outer function to continue and double-send to channel
				}
			}()
			bytes, err := os.ReadFile(filepath.Join(appliesDir, file.Name()))

			if err != nil {
				errCh <- fmt.Errorf("error reading apply file: %v", err)
				return
			}

			var apply PlanApply
			err = json.Unmarshal(bytes, &apply)

			if err != nil {
				errCh <- fmt.Errorf("error unmarshalling apply file: %v", err)
				return
			}

			mu.Lock()
			planApplies = append(planApplies, &apply)
			mu.Unlock()

			errCh <- nil
		}(file)
	}

	for i := 0; i < len(files); i++ {
		err := <-errCh
		if err != nil {
			return nil, fmt.Errorf("error getting plan applies: %v", err)
		}
	}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Validate each apply file with a JSON linter; find and fix/repair the malformed one (the wrapped error names the json offset/field).
  2. Restore the corrupt file from backup or remove it if it holds no needed data.
  3. Check disk space and prior crash logs to explain truncation.
  4. Upgrade the server if an old schema version wrote the file.
Defensive patterns

Strategy: validation

Validate before calling

files, _ := os.ReadDir(appliesDir)
for _, f := range files {
    raw, err := os.ReadFile(filepath.Join(appliesDir, f.Name()))
    if err == nil {
        var probe map[string]any
        if json.Unmarshal(raw, &probe) != nil {
            return fmt.Errorf("apply file %s is not valid JSON", f.Name())
        }
    }
}

Try / catch

applies, err := GetPlanApplies(orgId, planId)
if err != nil {
    if strings.Contains(err.Error(), "error unmarshalling apply file") {
        return nil, fmt.Errorf("a stored apply file is corrupt; inspect the applies dir: %w", err)
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling GetPlanApplies when any file in the applies dir is corrupt: crash mid-write, manual edit, zero-byte file, or on-disk schema drift from an older Plandex version.

Common situations: Server crash or power loss during an apply write; data restored from a partial backup; hand-rolled scripts writing into the applies directory.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/1d0aba2de7e551c8. Report an issue: GitHub.