vxcontrol/pentagi · error
failed to unmarshal %s search in memory action arguments: %w
Error message
failed to unmarshal %s search in memory action arguments: %w
What it means
The `search in memory` tool received tool-call arguments that could not be decoded into the `SearchInMemoryAction` struct. The LLM agent produced JSON that fails `json.Unmarshal` (malformed JSON, wrong types, or unknown/misspelled fields with strict typing). This library wraps the underlying decode error so the caller sees both the tool name and the JSON error.
Source
Thrown at backend/pkg/tools/memory.go:63
}
ctx, observation := obs.Observer.NewObservation(ctx)
logger := logrus.WithContext(ctx).WithFields(enrichLogrusFields(m.flowID, nil, nil, logrus.Fields{
"tool": name,
"args": string(args),
}))
if m.store == nil {
logger.Error("pgvector store is not initialized")
return "", fmt.Errorf("pgvector store is not initialized")
}
switch name {
case SearchInMemoryToolName:
var action SearchInMemoryAction
if err := json.Unmarshal(args, &action); err != nil {
logger.WithError(err).Error("failed to unmarshal search in memory action arguments")
return "", fmt.Errorf("failed to unmarshal %s search in memory action arguments: %w", name, err)
}
filters := map[string]any{
"flow_id": strconv.FormatInt(m.flowID, 10),
"doc_type": memoryVectorStoreDefaultType,
}
if action.TaskID != nil && *action.TaskID != 0 {
filters["task_id"] = action.TaskID.String()
}
if action.SubtaskID != nil && *action.SubtaskID != 0 {
filters["subtask_id"] = action.SubtaskID.String()
}
isSpecificFilters, globalFilters := getGlobalFilters(filters)
metadata := langfuse.Metadata{
"tool_name": name,
"message": action.Message,
"limit": memoryVectorStoreResultLimit,View on GitHub (pinned to ea665308ba)
Solutions
- Log and inspect the raw `args` string next to the wrapped error to see exactly what the model produced.
- Verify the tool's JSON schema advertised to the LLM matches the current `SearchInMemoryAction` struct fields and types.
- Check the inner `%w` error (e.g. `json: cannot unmarshal string into Go struct field ...`) to pinpoint the offending field.
- Retry the tool call; if a specific model repeatedly mis-formats arguments, switch provider or strengthen the tool description.
- If arguments come from your own code, marshal with `json.Marshal(SearchInMemoryAction{...})` instead of hand-built strings.
Example fix
// before
args := []byte(`{"questions": "what is x"}`) // questions must be an array
// after
args, _ := json.Marshal(SearchInMemoryAction{Questions: []string{"what is x"}}) Defensive patterns
Strategy: validation
Validate before calling
var probe map[string]any
if err := json.Unmarshal(args, &probe); err != nil {
return fmt.Errorf("invalid tool args JSON: %w", err)
}
q, ok := probe["questions"].([]any)
if !ok || len(q) == 0 {
return errors.New("questions must be a non-empty array of strings")
} Type guard
func isValidSearchInMemoryArgs(args []byte) bool {
var a struct{ Questions []string `json:"questions"` }
return json.Unmarshal(args, &a) == nil && len(a.Questions) > 0
} Try / catch
out, err := mem.Handle(ctx, tools.SearchInMemoryToolName, args)
if err != nil {
var jsonErr *json.UnmarshalTypeError
if errors.As(err, &jsonErr) {
logger.Warnf("malformed tool args: %v, raw=%s", err, string(args))
return retryToolCall(ctx) // ask the model to re-emit arguments
}
return err
} Prevention
- Always advertise the tool JSON schema generated from the Go struct, never a hand-written copy.
- Log raw tool arguments on every failure for post-mortem.
- Use providers/models with native structured/JSON tool-call output.
- Pin the action struct and regenerate the schema whenever fields change.
When it happens
Trigger: An agent invokes the `search_in_memory` tool via `memory.Handle(ctx, name, args)` with `name == SearchInMemoryToolName` and `args` bytes that json.Unmarshal cannot decode into `SearchInMemoryAction` — e.g. `questions` sent as a string instead of an array, truncated JSON, or a non-string `query` field.
Common situations: LLM providers emitting malformed tool-call JSON; prompt templates that show an outdated action schema; models wrapping arguments in markdown fences or extra nesting; a struct field type changed (e.g. `Questions []string` → string) while the model still emits the old shape.
Related errors
- failed to unmarshal %s search answer action arguments: %w
- failed to unmarshal %s store answer action arguments: %w
- failed to unmarshal primary agent msg chain %d: %w
- failed to unmarshal search arguments: %w
- failed to unmarshal %s search guide action arguments: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/8edd226745ce694a.
Report an issue: GitHub.