sipeed/picoclaw · error
apply draft failed
Error message
apply draft failed
What it means
Umbrella error from the evolution Runtime's apply step (applyCandidateDraft): the draft failed to apply via applier.applyDraftWithRollback, or post-apply persistence (SaveDrafts / SaveAppliedProfile) failed even after rollback was attempted. The real cause is appended with %v and often errors.Join-ed with audit/save errors; the draft is marked DraftStatusQuarantined and the reason is appended to draft.ScanFindings ("apply failed: ...").
Source
Thrown at pkg/evolution/runtime.go:22
"context"
"crypto/sha1"
"encoding/hex"
"errors"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"sync"
"time"
"unicode/utf8"
"github.com/sipeed/picoclaw/pkg/config"
"github.com/sipeed/picoclaw/pkg/logger"
"github.com/sipeed/picoclaw/pkg/skills"
)
var ErrApplyDraftFailed = errors.New("apply draft failed")
type RuntimeOptions struct {
Config config.EvolutionConfig
Now func() time.Time
Store *Store
Organizer *Organizer
PatternClusterer PatternClusterer
SuccessJudge SuccessJudge
SkillsRecaller *SkillsRecaller
DraftGenerator DraftGenerator
GeneratorFactory func(workspace string) DraftGenerator
SuccessJudgeFactory func(workspace string) SuccessJudge
Applier *Applier
ApplierFactory func(workspace string) *Applier
}
type Runtime struct {
cfg config.EvolutionConfigView on GitHub (pinned to 49183d7e8d)
Solutions
- Read the joined error chain and draft.ScanFindings — the tail after 'apply draft failed:' names the actual cause (apply error, save error, or rollback error)
- Verify the workspace skills directory is writable and that draft.TargetSkillName exists for update/change drafts
- Check the evolution store under PICOCLAW_HOME: permissions, disk space, no concurrent gateway instances (see pid file singleton)
- The failed draft is quarantined automatically and skipped by later runs — fix the root cause, then regenerate/re-run the evolution run instead of retrying the same quarantined draft
Defensive patterns
Strategy: try-catch
Validate before calling
// before triggering an evolution run
if err := checkWorkspaceWritable(workspaceSkillsDir); err != nil { return err }
if err := store.Load(); err != nil { return err } // store must be readable Type guard
func isApplyDraftFailed(err error) bool {
return errors.Is(err, evolution.ErrApplyDraftFailed)
} Try / catch
draft, err := rt.RunEvolution(ctx) // or the apply entry point
if err != nil {
if errors.Is(err, evolution.ErrApplyDraftFailed) {
// inspect draft.ScanFindings for 'apply failed: ...'; draft is quarantined,
// so fix the root cause and start a new run — do not retry the same draft
}
return err
} Prevention
- Keep the workspace skills directory and PICOCLAW_HOME store writable by the gateway user
- Run one evolution cycle at a time (the PID-file singleton also guards this)
- Monitor draft.Status == quarantined counts as an early signal of apply problems
When it happens
Trigger: Runtime evolution run where the generated SkillDraft fails to write/scan against workspace skill files, the evolution store file is unwritable or corrupt, or the post-apply profile save fails after files changed (triggering rollback, whose error is joined too).
Common situations: Workspace skills directory read-only or skill file missing for an update draft (TargetSkillName not found); $PICOCLAW_HOME store on a full disk or with wrong ownership; draft content produced by the generator rejected by the apply-time scan; concurrent runs writing the store.
Related errors
- skill frontmatter is required
- skill heading is required
- skill frontmatter name is required
- name is required
- description is required
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/dcdf27070a92375b.
Report an issue: GitHub.