cayleygraph/cayley · error
Datastore: invalid action
Error message
Datastore: invalid action
What it means
ApplyDeltas validates every delta's Action before applying it; only graph.Add and graph.Delete are supported. Any other action value causes an immediate abort of the whole batch — no partial application.
Source
Thrown at graph/gaedatastore/quadstore.go:216
return 0, err
}
return len(buf), nil
}
func (w *quadWriter) Close() error {
w.deltas = nil
return nil
}
func (qs *QuadStore) ApplyDeltas(in []graph.Delta, ignoreOpts graph.IgnoreOpts) error {
if qs.context == nil {
return errors.New("No context, graph not correctly initialised")
}
toKeep := make([]graph.Delta, 0)
for _, d := range in {
if d.Action != graph.Add && d.Action != graph.Delete {
//Defensive shortcut
return errors.New("Datastore: invalid action")
}
key := qs.createKeyForQuad(d.Quad)
keep := false
switch d.Action {
case graph.Add:
found, err := qs.checkValid(key)
if err != nil {
return err
}
if found {
if !ignoreOpts.IgnoreDup {
return graph.ErrQuadExists
}
} else {
keep = true
}
case graph.Delete:
found, err := qs.checkValid(key)View on GitHub (pinned to 81dcd7d73e)
Solutions
- Audit delta construction and set Action explicitly to graph.Add or graph.Delete for every delta.
- Validate the batch before calling ApplyDeltas and reject unknown actions early.
- Update code that uses an action value this backend does not support; the GAE datastore backend only implements Add/Delete.
- Check delta-producing helpers for paths that return an empty/zero Delta.
Example fix
// before
deltas = append(deltas, graph.Delta{Quad: q})
// after
deltas = append(deltas, graph.Delta{Quad: q, Action: graph.Add}) Defensive patterns
Strategy: validation
Validate before calling
for i, d := range deltas {
if d.Action != graph.Add && d.Action != graph.Delete {
return fmt.Errorf("delta %d has invalid action %v", i, d.Action)
}
} Type guard
func validActions(ds []graph.Delta) bool {
for _, d := range ds {
if d.Action != graph.Add && d.Action != graph.Delete { return false }
}
return true
} Try / catch
if err := qs.ApplyDeltas(deltas, ignoreOpts); err != nil {
if strings.Contains(err.Error(), "invalid action") {
// log offending batch, fix producer
}
return err
} Prevention
- Use constructor helpers for deltas that always set Action.
- Never rely on zero values for enum fields.
- Unit-test delta producers to assert valid actions.
- Validate batches at the boundary before store calls.
When it happens
Trigger: Passing a []graph.Delta to ApplyDeltas (or the wrappers WriteQuads/AddQuadSet/ApplyTransaction) where any delta has an Action other than graph.Add or graph.Delete (e.g. zero value, graph.Update, or corrupt delta).
Common situations: Constructing deltas manually and forgetting to set Action; building a Delta with a struct literal that omits the Action field so it defaults to zero; middleware that produces custom action codes.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- token not valid
- gae quad: token not valid
- Nothing to log
- cannot count iterator without a valid context
- ErrInvalidAction
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/6f18b5ff42923107.
Report an issue: GitHub.