## TL;DR
rate and its siblings need a range vector, a metric plus a time window like [5m], but the query handed them an instant vector. Add the range selector to the inner metric and the function gets the samples over time it needs.

```text
expected type range vector in call to function "rate"
```

## Steps

1. Find the offending call and look at what is inside it:
```bash
echo '[YOUR_QUERY]' | grep -o 'rate([^)]*)' | head -5
```
Expected: the rate call with its argument visible, showing whether the inner selector has a [DURATION] range.

2. Confirm the inner expression is an instant vector:
```bash
curl -s --data-urlencode "query=[INNER_EXPR]" http://YOUR-PROM_HOST:9090/api/v1/query | python3 -c "import json,sys; print(json.load(sys.stdin)['data']['resultType'])"
```
Expected: `vector`, proving the argument is an instant vector where a range vector is required.

3. Add the range selector to the inner metric:
```promql
rate([METRIC]{[LABELS]}[5m])
```
Expected: the expression now passes a range vector, and the type error is gone.

4. Pick a range that matches the scrape interval and the question:
```bash
# rule of thumb: range of at least 4x the scrape interval
# 15s scrape means [1m] minimum for stable rates; [5m] for dashboards
```
Expected: rates are smooth rather than spiky, and slow scrapes do not produce gaps.

5. Validate the fixed query end to end:
```bash
curl -s --data-urlencode "query=rate([METRIC]{[LABELS]}[5m])" http://YOUR-PROM_HOST:9090/api/v1/query_range --data-urlencode "start=[START]" --data-urlencode "end=[END]" --data-urlencode "step=60s" | python3 -c "import json,sys; print(json.load(sys.stdin)['status'])"
```
Expected: `success`, confirming the query type-checks and returns data.

## When to use
- rate, increase, irate, delta, or deriv fail with the expected range vector error
- A query copied from docs fails because the range selector was dropped
- Alerting rules fail to load with a function type error

## When not to use
- The error names a different expected type; read which type the function wants
- rate returns no data but no error; that is a missing metric or too-short range, not a type error
- You actually want the latest value; then drop rate and use the instant selector directly

## Why it happens
PromQL has two vector types: instant vectors (one value per series right now) and range vectors (values over a time window). Functions like rate compute per-second change from consecutive samples, which requires the window, so the type checker rejects an instant vector argument at parse time.

## Edge cases
- Aggregations like sum() return instant vectors, so rate(sum(metric)[5m]) works but sum(rate(metric[5m])) is usually what you want; order matters
- A range shorter than twice the scrape interval yields no data or wild spikes; keep the 4x rule
- irate uses only the last two samples in the range, so a long range does not smooth it the way it smooths rate
- Subquery ranges like rate(metric[5m:1m]) are valid but rarely needed; prefer the simple range selector

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_L86NmyFQ9LgQudyHkqVQyQ
