{"record":{"id":"c846a5c40e65f8df","repo":"vxcontrol/pentagi","slug":"failed-to-unmarshal-s-search-guide-action-argumen","errorCode":null,"errorMessage":"failed to unmarshal %s search guide action arguments: %w","messagePattern":"failed to unmarshal (.+?) search guide action arguments: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/guide.go","lineNumber":91,"sourceCode":"\t}\n\n\tctx, observation := obs.Observer.NewObservation(ctx)\n\tlogger := logrus.WithContext(ctx).WithFields(enrichLogrusFields(g.flowID, g.taskID, g.subtaskID, logrus.Fields{\n\t\t\"tool\": name,\n\t\t\"args\": string(args),\n\t}))\n\n\tif g.store == nil {\n\t\tlogger.Error(\"pgvector store is not initialized\")\n\t\treturn \"\", fmt.Errorf(\"pgvector store is not initialized\")\n\t}\n\n\tswitch name {\n\tcase SearchGuideToolName:\n\t\tvar action SearchGuideAction\n\t\tif err := json.Unmarshal(args, &action); err != nil {\n\t\t\tlogger.WithError(err).Error(\"failed to unmarshal search guide action\")\n\t\t\treturn \"\", fmt.Errorf(\"failed to unmarshal %s search guide action arguments: %w\", name, err)\n\t\t}\n\n\t\tfilters := map[string]any{\n\t\t\t\"doc_type\":   guideVectorStoreDefaultType,\n\t\t\t\"guide_type\": action.Type,\n\t\t}\n\n\t\tmetadata := langfuse.Metadata{\n\t\t\t\"tool_name\":     name,\n\t\t\t\"message\":       action.Message,\n\t\t\t\"limit\":         guideVectorStoreResultLimit,\n\t\t\t\"threshold\":     guideVectorStoreThreshold,\n\t\t\t\"doc_type\":      guideVectorStoreDefaultType,\n\t\t\t\"guide_type\":    action.Type,\n\t\t\t\"queries_count\": len(action.Questions),\n\t\t}\n\n\t\tretriever := observation.Retriever(","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/guide.go#L73-L109","documentation":"The search_guide tool received LLM-generated arguments that could not be parsed as JSON into SearchGuideAction. The agent's function-calling output did not match the tool's JSON schema, so the guide.Handle dispatcher aborts before running the vector store search.","triggerScenarios":"Agent model emits malformed JSON for the search_guide tool call (e.g. unquoted strings, trailing commas, wrong field names/types like guide_type as a number), or args contains text/prose instead of a JSON object.","commonSituations":"Weaker LLMs or providers with relaxed function-calling emitting invalid JSON; prompt templates changed so the schema example no longer matches; a provider returning tool args wrapped in markdown fences; version drift between tool schema in provider prompts and the Go struct.","solutions":["Log the raw args string (already captured in logrus field 'args') and inspect exactly what the model produced.","Re-generate the flow / retry the agent turn — often a single malformed sample from the model.","Check that the tool JSON schema advertised to the LLM matches SearchGuideAction fields (type, message, questions) and their requiredness.","If a specific provider consistently fails, tighten its function-calling mode or switch to a provider with strict JSON output.","If the model can't produce valid JSON reliably, add pre-parse cleanup (strip code fences) before json.Unmarshal."],"exampleFix":"// before: unmarshal raw args directly\nif err := json.Unmarshal(args, &action); err != nil { ... }\n\n// after: defensively strip a common LLM artifact (markdown fences)\ncleaned := bytes.Trim(bytes.TrimSpace(args), \"` \\n\")\ncleaned = bytes.TrimPrefix(bytes.TrimPrefix(cleaned, []byte(\"json\")), []byte(\"\\n\"))\nif err := json.Unmarshal(cleaned, &action); err != nil {\n    return \"\", fmt.Errorf(\"failed to unmarshal %s search guide action arguments: %w\", name, err)\n}","handlingStrategy":"validation","validationCode":"func isValidSearchGuideArgs(args json.RawMessage) bool {\n    var probe struct {\n        Type      string   `json:\"type\"`\n        Questions []string `json:\"questions\"`\n    }\n    return json.Unmarshal(args, &probe) == nil && probe.Type != \"\"\n}","typeGuard":"func asSearchGuideAction(args json.RawMessage) (*SearchGuideAction, bool) {\n    var a SearchGuideAction\n    if err := json.Unmarshal(args, &a); err != nil || a.Type == \"\" {\n        return nil, false\n    }\n    return &a, true\n}","tryCatchPattern":"res, err := tool.Handle(ctx, \"search_guide\", args)\nif err != nil {\n    var jsonErr *json.UnmarshalTypeError\n    if errors.As(err, &jsonErr) {\n        log.Printf(\"invalid tool args (field %s): %v\", jsonErr.Field, err)\n        return retryWithCorrectedSchema()\n    }\n    return err\n}","preventionTips":["Enable strict JSON mode on the LLM provider for function calling","Log the raw args payload on every tool call for post-mortem","Keep the tool JSON schema in prompts in sync with SearchGuideAction","Strip markdown fences from model output before unmarshaling"],"tags":["json","unmarshal","tool-arguments","llm"],"backgroundTag":"json-unmarshal-tool-args","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}