Skip to content

fix(api): warn when endpoint contains "?" to prevent silent shell truncation#1264

Draft
DaveHanns wants to merge 1 commit into
apify:masterfrom
DaveHanns:fix/api-endpoint-shell-metacharacters
Draft

fix(api): warn when endpoint contains "?" to prevent silent shell truncation#1264
DaveHanns wants to merge 1 commit into
apify:masterfrom
DaveHanns:fix/api-endpoint-shell-metacharacters

Conversation

@DaveHanns

Copy link
Copy Markdown
Contributor

Summary

Running apify api with an unquoted endpoint that contains a query string is silently truncated by the shell, so the CLI ends up hitting a different URL than the user intended. This PR detects the tell-tale ? in the endpoint arg and emits a stderr warning pointing at two safe forms.

Reproducer

$ apify api /v2/acts?my=1&limit=100

The shell interprets & as the background operator, so the CLI process only receives /v2/acts?my=1 in argv; limit=100 is discarded. The request returns a much larger response than the caller expected (no limit), and there is no indication that anything was dropped. In practice this pushes users (and agents) to abandon apify api and fall back to raw curl, e.g.:

curl -s -H "Authorization: Bearer $APIFY_TOKEN" "https://api.apify.com/v2/acts?my=1&limit=100" | ...

? on its own can also be expanded by the shell as a glob if a matching filename happens to exist in the current directory.

Fix

The CLI cannot see the missing & (the shell consumed it before execve), but the leftover ? in the endpoint is a strong signal that inline query parameters were being passed. When the endpoint contains ?, print a stderr warning with two concrete fixes:

Warning: The endpoint contains a "?". If the command line was not fully
quoted, the shell may have silently dropped everything after an unquoted "&"
or expanded "?" as a glob. Prefer --params to pass query parameters, e.g.
  apify api /v2/acts -p '{"my":1,"limit":100}'
or quote the whole endpoint:
  apify api '/v2/acts?my=1&limit=100'

The warning is stderr-only and does not change exit code or behavior, so this is fully backward-compatible for callers who already quote correctly. The same guidance is added to the command description so apify api --help teaches it too.

Test plan

  • apify api /v2/acts?my=1&limit=100 (unquoted) — stderr warning shown, request still proceeds.
  • apify api '/v2/acts?my=1&limit=100' — warning shown (same signal, same guidance), request proceeds correctly.
  • apify api /v2/users/me — no warning.
  • apify api /v2/acts -p '{"my":1,"limit":100}' — no warning; recommended form.
  • pnpm test test/local/commands/api.test.ts — new coverage in describe('inline query-string detection', ...) plus all existing api tests still pass (27/27).
  • pnpm run update-docsdocs/reference.md regenerated from the updated description; no stale content.

Surfaced during an evaluation of Apify surfaces for agent-driven Actor development.

…ncation

Running `apify api /v2/acts?my=1&limit=100` from an unquoted shell backgrounds
the command at `&` and passes only `/v2/acts?my=1` to the CLI. The rest is
silently dropped and the request returns something the caller did not ask for.

The CLI can never see the `&` (the shell consumed it), but the leftover `?` in
the endpoint is a strong signal that inline query parameters were intended. Emit
a stderr warning in that case with two concrete fixes:

  apify api /v2/acts -p '{"my":1,"limit":100}'
  apify api '/v2/acts?my=1&limit=100'

Also mention this in the command description so `--help` teaches the same thing.

Surfaced during an evaluation of Apify surfaces for agent-driven Actor development.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@DaveHanns DaveHanns requested review from l2ysho and szaganek as code owners July 4, 2026 23:09
@DaveHanns DaveHanns marked this pull request as draft July 5, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants