rtk-ai/rtk · error
rtk find does not support compound predicates or actions…
Error message
rtk find does not support compound predicates or actions (e.g. -not, -exec). Use `find` directly.
What it means
RTK's find replacement (parse_find_args in src/cmds/system/find_cmd.rs) supports only simple searches: its compact syntax (`rtk find '*.rs' [path] [-m max] [-t type]`) and single-predicate native syntax (`-name`, `-type`, `-maxdepth`, ...). Before parsing it scans argv for UNSUPPORTED_FIND_FLAGS — `-not`, `!`, `-or`, `-o`, `-and`, `-a`, `-exec`, `-execdir`, `-delete`, `-print0`, `-newer`, and friends — and aborts on any exact-token match. This is a deliberate scope limit: silently mishandling compound predicates or side-effecting actions would return wrong or destructive results, so rtk refuses and points you at the real `find`.
Solutions
- Run the system `find` directly for compound predicates or actions; wrap with `rtk proxy find ...` if you still want it counted in rtk's usage stats.
- Rewrite as a simple predicate rtk supports: `rtk find '*.rs' -t f` or `rtk find . -name '*.rs' -type f -maxdepth 3`.
- For -exec/-delete effects, use find itself or a small shell loop — rtk deliberately avoids reproducing side-effecting actions.
Example fix
# before rtk find . -name '*.tmp' -not -name '*.keep' -delete # after — use the real find (rtk supports neither -not nor -delete) find . -name '*.tmp' -not -name '*.keep' -delete # or keep it in rtk usage stats: rtk proxy find . -name '*.tmp' -not -name '*.keep' -delete
Defensive patterns
Strategy: validation
Validate before calling
# bash — pre-check the tokens rtk find rejects before invoking it
UNSUPPORTED='-not ! -or -o -and -a -exec -execdir -delete -print0 -newer'
for a in "$@"; do
case " $UNSUPPORTED " in
*" $a "*) exec find "$@" ;; # compound predicate -> real find
esac
done
rtk find "$@" Type guard
rtk_find_safe() {
# returns 0 when no argv token is in rtk find's unsupported-flag set
local a
for a in "$@"; do
case " $a " in
' -not '|' ! '|' -or '|' -o '|' -and '|' -a '|' -exec '|' -execdir '|' -delete '|' -print0 '|' -newer ') return 1 ;;
esac
done
return 0
} Try / catch
out=$(rtk find "$@" 2>&1) || {
case "$out" in
*'compound predicates'*) exec find "$@" ;; # deliberate scope limit -> raw find
esac
printf '%s\n' "$out" >&2; exit 1
}
printf '%s\n' "$out" Prevention
- Keep a mental split: rtk find for quick simple lookups, system find for anything with -not/-exec/-delete/-newer.
- In agent prompts, state that compound find predicates must call find directly (or via rtk proxy find).
- When in doubt, `rtk proxy find ...` always works and still records usage.
When it happens
Trigger: Any `rtk find` invocation containing a token from UNSUPPORTED_FIND_FLAGS, e.g. `rtk find . -name '*.rs' -not -name '*_test.rs'`, `rtk find . -exec rm {} \;`, `rtk find . -newer ref -type f`, `rtk find . -name '*.tmp' -delete`.
Common situations: Agents piping every find through rtk by habit; muscle-memory GNU find idioms with -not/-exec; scripts assuming rtk find is a drop-in find replacement.
Related errors
- ambiguous hash prefix
- Antigravity is project-scoped. Use: rtk init --agent…
- at least one of install_claude or install_opencode must be…
- bunx requires a command argument
- --codex cannot be combined with --auto-patch
AI-assisted analysis of rtk-ai/rtk@29f9bb7161 (2026-08-20).
Data as JSON: /api/errors/be3ba4f8b2f5b626.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmds/system/find_cmd.rs:89
"-regex", "-iregex",
];
fn has_unsupported_find_flags(args: &[String]) -> bool {
args.iter()
.any(|a| UNSUPPORTED_FIND_FLAGS.contains(&a.as_str()))
}
/// Parse arguments from raw args vec, supporting both native find and RTK syntax.
///
/// Native find syntax: `find . -name "*.rs" -type f -maxdepth 3`
/// RTK syntax: `find *.rs [path] [-m max] [-t type]`
fn parse_find_args(args: &[String]) -> Result<FindArgs> {
if args.is_empty() {
return Ok(FindArgs::default());
}
if has_unsupported_find_flags(args) {
anyhow::bail!(
"rtk find does not support compound predicates or actions (e.g. -not, -exec). Use `find` directly."
);
}
if has_native_find_flags(args) {
parse_native_find_args(args)
} else {
parse_rtk_find_args(args)
}
}
/// Parse native find syntax: `find [path] -name "*.rs" -type f -maxdepth 3`
fn parse_native_find_args(args: &[String]) -> Result<FindArgs> {
let mut parsed = FindArgs::default();
let mut i = 0;
// First non-flag argument is the path (standard find behavior)
if !args[0].starts_with('-') {View on GitHub (pinned to 29f9bb7161)