{"record":{"id":"f1c291a1529c9c6b","repo":"dgraph-io/dgraph","slug":"out-of-range-for-peek","errorCode":null,"errorMessage":"Out of range for peek","messagePattern":"Out of range for peek","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lex/lexer.go","lineNumber":116,"sourceCode":"\t}\n\treturn false\n}\n\n// Restore restores the iterator to position specified.\nfunc (p *ItemIterator) Restore(pos int) {\n\tx.AssertTrue(pos <= len(p.l.items) && pos >= -1)\n\tp.idx = pos\n}\n\n// Save returns the current position of the iterator which we can use for restoring later.\nfunc (p *ItemIterator) Save() int {\n\treturn p.idx\n}\n\n// Peek returns the next n items without consuming them.\nfunc (p *ItemIterator) Peek(num int) ([]Item, error) {\n\tif (p.idx + num + 1) > len(p.l.items) {\n\t\treturn nil, errors.Errorf(\"Out of range for peek\")\n\t}\n\treturn p.l.items[p.idx+1 : p.idx+num+1], nil\n}\n\n// PeekOne returns the next 1 item without consuming it.\nfunc (p *ItemIterator) PeekOne() (Item, bool) {\n\tif p.idx+1 >= len(p.l.items) {\n\t\treturn Item{\n\t\t\tline:   -1,\n\t\t\tcolumn: -1, // use negative number to indicate out of range\n\t\t}, false\n\t}\n\treturn p.l.items[p.idx+1], true\n}\n\n// A RuneWidth represents a consecutive string of runes with the same width\n// and the number of runes is stored in count.\n// The reason we maintain this information is to properly backup when multiple look-aheads happen.","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/lex/lexer.go#L98-L134","documentation":"ItemIterator.Peek returns the next num items without consuming them, but it rejects the request when the peek window extends past the end of the buffered lexed items. The parser calls Peek while deciding how to parse expressions (math functions, variable names, arguments, geo arguments, function calls, cascade directives), and this error signals the token stream simply ended.","triggerScenarios":"Calling ItemIterator.Peek(num) when p.idx + num + 1 >= len(items); practically, this happens when the parser tries to look ahead past the end of the query, e.g. a query that stops mid-expression like 'math(' or an incomplete function argument list.","commonSituations":"Truncated queries sent to Dgraph: network tooling cut the request, a template rendered only part of the query, or a user submitted an unfinished query ending right after a function name or opening parenthesis.","solutions":["Inspect the query around the reported position and complete the truncated expression (add the missing arguments/closing parenthesis)","Ensure the HTTP body/gRPC payload is not being truncated by proxies or string-size limits","Wrap parser calls and surface a clearer 'unexpected end of query' message to users","If writing Go code against the lexer directly, call PeekOne (returns bool) or check iterator bounds before Peek"],"exampleFix":"// before\nitems, err := it.Peek(3) // err: Out of range for peek on 'func: eq(name'\n// after\nitems, err := it.Peek(3)\nif err != nil {\n    return fmt.Errorf(\"query ended unexpectedly while parsing %q: %w\", partial, err)\n}","handlingStrategy":"validation","validationCode":"// Guard: does the query text end mid-expression?\nif strings.HasSuffix(strings.TrimSpace(q), \"(\") || strings.HasSuffix(strings.TrimSpace(q), \",\") {\n    return fmt.Errorf(\"query appears truncated: %q\", q)\n}","typeGuard":null,"tryCatchPattern":"items, err := it.Peek(n)\nif err != nil {\n    // token stream exhausted: treat as unexpected-end-of-query\n    return fmt.Errorf(\"unexpected end of query while parsing: %w\", err)\n}","preventionTips":["Verify request bodies are not truncated by proxies or client buffers","Complete all function argument lists and parentheses before sending","Use DQL client libraries/builders instead of hand-assembled strings"],"tags":["lexer","parser","lookahead","truncated-query"],"backgroundTag":"dql-syntax-error","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}