{"record":{"id":"be3ba4f8b2f5b626","repo":"rtk-ai/rtk","slug":"rtk-find-does-not-support-compound-predicates-or-a","errorCode":null,"errorMessage":"rtk find does not support compound predicates or actions (e.g. -not, -exec). Use `find` directly.","messagePattern":"rtk find does not support compound predicates or actions \\(e\\.g\\. -not, -exec\\)\\. Use `find` directly\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmds/system/find_cmd.rs","lineNumber":89,"sourceCode":"    \"-regex\", \"-iregex\",\n];\n\nfn has_unsupported_find_flags(args: &[String]) -> bool {\n    args.iter()\n        .any(|a| UNSUPPORTED_FIND_FLAGS.contains(&a.as_str()))\n}\n\n/// Parse arguments from raw args vec, supporting both native find and RTK syntax.\n///\n/// Native find syntax: `find . -name \"*.rs\" -type f -maxdepth 3`\n/// RTK syntax: `find *.rs [path] [-m max] [-t type]`\nfn parse_find_args(args: &[String]) -> Result<FindArgs> {\n    if args.is_empty() {\n        return Ok(FindArgs::default());\n    }\n\n    if has_unsupported_find_flags(args) {\n        anyhow::bail!(\n            \"rtk find does not support compound predicates or actions (e.g. -not, -exec). Use `find` directly.\"\n        );\n    }\n\n    if has_native_find_flags(args) {\n        parse_native_find_args(args)\n    } else {\n        parse_rtk_find_args(args)\n    }\n}\n\n/// Parse native find syntax: `find [path] -name \"*.rs\" -type f -maxdepth 3`\nfn parse_native_find_args(args: &[String]) -> Result<FindArgs> {\n    let mut parsed = FindArgs::default();\n    let mut i = 0;\n\n    // First non-flag argument is the path (standard find behavior)\n    if !args[0].starts_with('-') {","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/rtk-ai/rtk/blob/d977e1c31621fe8704e6500ceeb9c7a0de2b6836/src/cmds/system/find_cmd.rs#L71-L107","documentation":"RTK's find wrapper deliberately supports only a small subset of native find (-name, -iname, -type, -maxdepth plus RTK's own short syntax). parse_find_args first scans args against UNSUPPORTED_FIND_FLAGS — -not, !, -or, -o, -and, -a, -exec, -execdir, -delete, -print0, -newer, -perm, -size, -mtime/-mmin/-atime/-amin/-ctime/-cmin, -empty, -link, -regex, -iregex — and hard-fails instead of silently mis-executing a predicate it cannot honor.","triggerScenarios":"Any `rtk find` (or hook-rewritten `find`) invocation containing a blacklisted token as a standalone argument: `find /tmp -name '*.log' -mtime +7 -delete` (-mtime, -delete), compound predicates with -o/-not, actions like -exec rm {} \\; or -print0, or -size/-perm tests.","commonSituations":"The rtk hook rewrites plain `find` to `rtk find`, so long-standing cleanup one-liners (-mtime +7 -delete, -exec) suddenly fail after installing hooks; agents using -print0 for null-safe xargs pipelines; scripts mixing RTK short syntax with native flags.","solutions":["Run the real binary directly: `find . -name '*.tmp' -mtime +7 -delete`; if the rtk hook rewrites it, escape with `command find ...`","Use `rtk proxy find ...` to run native find unfiltered while still tracking usage","Stay within the supported subset: `rtk find . -name '*.rs' -type f -maxdepth 3`, or RTK syntax `rtk find '*.rs' . -t f -m 20`"],"exampleFix":"# before (hook rewrites find -> rtk find; -mtime/-delete are blacklisted)\nfind /tmp -name '*.log' -mtime +7 -delete\n# rtk: rtk find does not support compound predicates or actions...\n\n# after\ncommand find /tmp -name '*.log' -mtime +7 -delete\n# or\nrtk proxy find /tmp -name '*.log' -mtime +7 -delete","handlingStrategy":"fallback","validationCode":"bash:\n# detect blacklisted flags and bypass rtk before it can fail\nUNSUPPORTED='-not ! -or -o -and -a -exec -execdir -delete -print0 -newer -perm -size -mtime -mmin -atime -amin -ctime -cmin -empty -link -regex -iregex'\nfor a in \"$@\"; do\n  case \" $UNSUPPORTED \" in *\" $a \"*) exec command find \"$@\";; esac\ndone\nrtk find \"$@\"","typeGuard":"rust:\nconst UNSUPPORTED_FIND_FLAGS: &[&str] = &[\n    \"-not\", \"!\", \"-or\", \"-o\", \"-and\", \"-a\", \"-exec\", \"-execdir\", \"-delete\", \"-print0\", \"-newer\",\n    \"-perm\", \"-size\", \"-mtime\", \"-mmin\", \"-atime\", \"-amin\", \"-ctime\", \"-cmin\", \"-empty\", \"-link\",\n    \"-regex\", \"-iregex\",\n];\nfn is_supported_find_args(args: &[String]) -> bool {\n    args.iter().all(|a| !UNSUPPORTED_FIND_FLAGS.contains(&a.as_str()))\n}","tryCatchPattern":"rust:\nmatch find_cmd::run(&args, verbose) {\n    Err(e) if e.to_string().contains(\"compound predicates\") => {\n        // fall back to the real find, unfiltered\n        let status = std::process::Command::new(\"find\").args(&args).status()?;\n        std::process::exit(status.code().unwrap_or(1));\n    }\n    r => r?,\n}","preventionTips":["Treat rtk find as a fast path for -name/-iname/-type/-maxdepth only","Default to `command find` or `rtk proxy find` for -exec/-delete/-mtime pipelines","When hooks rewrite find, remember `command find` escapes the rewrite","Watch for bare `!` — it is in the blacklist, not just the word -not"],"tags":["find","filesystem","usage","unsupported-feature","hooks"],"backgroundTag":null,"analyzedSha":"d977e1c31621fe8704e6500ceeb9c7a0de2b6836","analyzedAt":"2026-08-16T05:40:46.291Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}