{"record":{"id":"8b27fccfb938c49e","repo":"langchain-ai/deepagents","slug":"context-lines-must-be-non-negative","errorCode":null,"errorMessage":"context_lines must be non-negative","messagePattern":"context_lines must be non-negative","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/backends/filesystem.py","lineNumber":653,"sourceCode":"                `None` returns every match; an int stops the search once the cap\n                is reached and flags the result with `truncated=True`.\n            context_lines: Number of lines to include before and after each match.\n\n                This is a backend-level API. It is deliberately not exposed\n                through the agent-facing `grep` tool (`GrepSchema`), so matches\n                returned via that tool never carry context.\n\n        Returns:\n            `GrepResult` with matches or error. When `context_lines > 0` and some\n            matched files cannot be re-read for context, the matches are still\n            returned and the failure is reported in `GrepResult.error`.\n\n        Raises:\n            ValueError: If `context_lines` is negative.\n        \"\"\"\n        if context_lines < 0:\n            msg = \"context_lines must be non-negative\"\n            raise ValueError(msg)\n\n        # Validate the include glob before choosing a search path: the shared\n        # matcher refuses some patterns (e.g. any `..` segment) by raising, and\n        # the Python fallback compiles it outside any error handling. Reporting\n        # a refusal here keeps `grep` non-throwing on both paths -- and\n        # consistent, since ripgrep would otherwise treat it as a silent\n        # no-match.\n        glob_refusal = self._refused_grep_glob_error(glob)\n        if glob_refusal is not None:\n            return GrepResult(error=glob_refusal, matches=[])\n\n        # Resolve base path\n        try:\n            base_full = self._resolve_path(path or \".\")\n        except ValueError:\n            return GrepResult(matches=[])\n        except (OSError, RuntimeError) as e:\n            search_path = path or \".\"","sourceCodeStart":635,"sourceCodeEnd":671,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/backends/filesystem.py#L635-L671","documentation":"grep validates its context_lines argument eagerly and rejects negative values with ValueError. Negative context is meaningless (it controls how many surrounding lines accompany each match), so the backend fails fast instead of producing slice-index bugs downstream.","triggerScenarios":"Calling grep(pattern, path, glob, context_lines=-1) or passing a negative value computed from subtraction (e.g. line_num - margin where margin > line_num).","commonSituations":"Computing context windows dynamically where an offset can go below zero, or off-by-one in tool wrappers around grep.","solutions":["Clamp context_lines with max(0, context_lines) before calling grep","Fix the arithmetic that produced the negative window size","Use 0 explicitly when no surrounding context is wanted"],"exampleFix":"// before\nresult = backend.grep(pattern, context_lines=before - after)\n// after\nresult = backend.grep(pattern, context_lines=max(0, before - after))","handlingStrategy":"validation","validationCode":"context_lines = max(0, context_lines)\nresult = backend.grep(pattern, context_lines=context_lines)","typeGuard":null,"tryCatchPattern":"try:\n    hits = backend.grep(pattern, context_lines=ctx)\nexcept ValueError as exc:\n    if \"context_lines must be non-negative\" in str(exc):\n        hits = backend.grep(pattern, context_lines=0)\n    else:\n        raise","preventionTips":["Clamp computed context sizes with max(0, ...)","Never pass raw subtraction results as window sizes"],"tags":["python","argument-validation","grep"],"backgroundTag":"negative-argument-value","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}