{"record":{"id":"54ddecda2a094b07","repo":"Tencent/WeKnora","slug":"args-must-be-a-string-or-an-array-of-strings-w","errorCode":null,"errorMessage":"args must be a string or an array of strings: %w","messagePattern":"args must be a string or an array of strings: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/skill_execute.go","lineNumber":116,"sourceCode":"\t\treturn err\n\t}\n\n\ti.SkillName = raw.SkillName\n\ti.ScriptPath = raw.ScriptPath\n\ti.Input = raw.Input\n\ti.Args = nil\n\n\tif len(raw.Args) == 0 || string(raw.Args) == \"null\" {\n\t\treturn nil\n\t}\n\n\tif err := json.Unmarshal(raw.Args, &i.Args); err == nil {\n\t\treturn nil\n\t}\n\n\tvar argsString string\n\tif err := json.Unmarshal(raw.Args, &argsString); err != nil {\n\t\treturn fmt.Errorf(\"args must be a string or an array of strings: %w\", err)\n\t}\n\n\t// Some providers emit the array as a stringified JSON payload\n\t// (e.g. \"[\\\"--project-name\\\",\\\"X\\\"]\"). Treat that as an array first so the\n\t// model's intent is preserved; strings.Fields would otherwise split the\n\t// brackets/quotes into garbage tokens and the script would see nonsense argv.\n\tif err := json.Unmarshal([]byte(argsString), &i.Args); err == nil {\n\t\treturn nil\n\t}\n\n\t// A plain string is interpreted as a conventional space-separated command\n\t// line. The tool schema continues to advertise []string, so well-formed\n\t// calls are unaffected; this is only a compatibility fallback for model\n\t// output.\n\ti.Args = strings.Fields(argsString)\n\treturn nil\n}\n","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/agent/tools/skill_execute.go#L98-L134","documentation":"SkillExecuteTool's UnmarshalJSON wraps a json.Unmarshal failure when the raw Args payload is neither a JSON array of strings nor a JSON string. The tool accepts argv arrays (or a stringified array) and rejects any other JSON shape, wrapping the underlying json error with %w so it can be errors.Is/As inspected.","triggerScenarios":"A provider emits Args as a JSON object (e.g. {\"flag\":\"value\"}), a number, boolean, or null, and the wrapped json.Unmarshal into []string and then into string both fail.","commonSituations":"Model tool-calls that pass named key/value arguments instead of an argv array; hand-written tool payloads using an unsupported shape; provider SDKs serializing arguments as objects.","solutions":["Change the Args payload to a JSON array of strings, e.g. [\"--flag\",\"value\"].","If the provider only supports objects, map the object to an argv array before unmarshalling.","Inspect the wrapped error with errors.As(*json.UnmarshalTypeError) to identify the offending shape."],"exampleFix":"// before\n{\"tool\": \"skill_execute\", \"args\": {\"project-name\": \"X\"}}\n// after\n{\"tool\": \"skill_execute\", \"args\": [\"--project-name\", \"X\"]}","handlingStrategy":"validation","validationCode":"switch v := any(raw.Args).(type) {\ncase []any, string:\n    // acceptable shapes\ndefault:\n    return fmt.Errorf(\"args must be a string or array of strings, got %T\", v)\n}","typeGuard":"func validArgsShape(raw json.RawMessage) bool {\n    var arr []string\n    var s string\n    return json.Unmarshal(raw, &arr) == nil || json.Unmarshal(raw, &s) == nil\n}","tryCatchPattern":"if err := json.Unmarshal(payload, &input); err != nil {\n    var jerr *json.UnmarshalTypeError\n    if errors.As(err, &jerr) && strings.Contains(err.Error(), \"args must be a string or an array of strings\") {\n        // convert object args to argv array and retry\n    }\n}","preventionTips":["Emit tool arguments as a JSON array of strings (argv style)","Convert provider object-style arguments to arrays before dispatch","Log the raw Args JSON when unmarshalling fails to spot shape mismatches early"],"tags":["json","unmarshal","tool-input"],"backgroundTag":"json-unmarshal-type-error","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}