{"record":{"id":"0fafa98ff9a99663","repo":"dgraph-io/dgraph","slug":"malformed-option-in-similar-to-expected-key-value","errorCode":null,"errorMessage":"Malformed option in similar_to: expected key:value pairs, got %v","messagePattern":"Malformed option in similar_to: expected key:value pairs, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"worker/task.go","lineNumber":2779,"sourceCode":"\t}\n\n\tif err := posting.MemLayerInstance.IterateDisk(ctx, *iteratorFunc); err != nil {\n\t\treturn err\n\t}\n\tspan.AddEvent(\"handleHasFunction result\", trace.WithAttributes(\n\t\tattribute.Int(\"uid_count\", len(result.Uids))))\n\tout.UidMatrix = append(out.UidMatrix, result)\n\treturn nil\n}\n\n// parseSimilarToOptions parses named options passed after similar_to 2 mandatory args (k, vecOrUid)\n// The parser encodes these as key/value pairs: [\"ef\", \"64\", \"distance_threshold\", \"0.5\", ...]\nfunc parseSimilarToOptions(args []string, fc *functionContext) error {\n\tif len(args) == 0 {\n\t\treturn nil\n\t}\n\tif len(args)%2 != 0 {\n\t\treturn errors.Errorf(\"Malformed option in similar_to: expected key:value pairs, got %v\", args)\n\t}\n\tseen := make(map[string]struct{}, len(args)/2)\n\tfor i := 0; i < len(args); i += 2 {\n\t\tk := strings.ToLower(strings.TrimSpace(args[i]))\n\t\tv := strings.TrimSpace(args[i+1])\n\t\tif strings.HasSuffix(k, \":\") {\n\t\t\tk = strings.TrimSuffix(k, \":\")\n\t\t}\n\t\tif len(k) == 0 {\n\t\t\treturn errors.Errorf(\"Malformed option in similar_to: empty key\")\n\t\t}\n\t\tif _, dup := seen[k]; dup {\n\t\t\treturn errors.Errorf(\"Duplicate key in similar_to options: %q\", k)\n\t\t}\n\t\tseen[k] = struct{}{}\n\n\t\tv = strings.Trim(v, \"\\\"'\")\n\t\tswitch k {","sourceCodeStart":2761,"sourceCodeEnd":2797,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/worker/task.go#L2761-L2797","documentation":"The similar_to vector-similarity function accepts extra options as flat key/value pairs (e.g. ef, distance_threshold). parseSimilarToOptions requires an even number of argument tokens; an odd list means a key without its value, so parsing fails.","triggerScenarios":"Calling similar_to with options like [\"ef\", \"64\", \"distance_threshold\"] — the trailing key has no value, making len(args) odd.","commonSituations":"Missing the numeric value after an option name in the query string; a template or client library dropping the last argument; copy-paste truncation of the query.","solutions":["Ensure every option key is followed by its value: similar_to(a, 10, [v], \"ef\", \"64\", \"distance_threshold\", \"0.5\").","Count your option tokens — they must be an even number of key:value pairs.","Check the client library/query template isn't dropping the last option value."],"exampleFix":"// before\nq(func: similar_to(a, 10, [0.1,0.2], \"ef\", \"64\", \"distance_threshold\"))\n// after\nq(func: similar_to(a, 10, [0.1,0.2], \"ef\", \"64\", \"distance_threshold\", \"0.5\"))","handlingStrategy":"validation","validationCode":"function validateSimilarToOptions(opts) {\n  if (!Array.isArray(opts)) return;\n  if (opts.length % 2 !== 0)\n    throw new Error(`similar_to options must be key:value pairs, got ${opts.length} tokens`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await txn.query(query);\n} catch (e) {\n  if (/Malformed option in similar_to/.test(String(e))) {\n    // rebuild the option list as complete key/value pairs\n  }\n  throw e;\n}","preventionTips":["Always emit option name AND value together.","Log the final rendered query before sending to catch truncation.","Validate even token count in query builders."],"tags":["dgraph","vector","similar-to","options"],"backgroundTag":"malformed-function-options","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}