multica-ai/multica · warning
move position is out of range
Error message
move position is out of range
What it means
issueMovePosition's single-anchor branches append with a fixed step: position = before + 1 (move below the anchor) or position = after - 1 (move above it). If that arithmetic overflows to ±Inf or produces NaN — which requires the anchor to be at or near the float64 maximum (or minimum for the subtract branch) — the result is rejected as out of range. In normal operation positions stay near zero, so hitting this indicates corrupted or adversarial position values, not ordinary use.
Source
Thrown at server/internal/handler/issue_move.go:205
return &position, true
}
func issueMovePosition(current float64, before, after *float64) (float64, error) {
switch {
case before != nil && after != nil:
if !(*before < *after) {
return 0, errors.New("move anchors are stale or out of order")
}
position := *before + (*after-*before)/2
if !(position > *before && position < *after) ||
math.IsInf(position, 0) || math.IsNaN(position) {
return 0, errors.New("move anchors are too close; refresh and retry")
}
return position, nil
case before != nil:
position := *before + 1
if math.IsInf(position, 0) || math.IsNaN(position) {
return 0, errors.New("move position is out of range")
}
return position, nil
case after != nil:
position := *after - 1
if math.IsInf(position, 0) || math.IsNaN(position) {
return 0, errors.New("move position is out of range")
}
return position, nil
default:
return current, nil
}
}
View on GitHub (pinned to 2c0912b6ec)
Solutions
- Identify the corrupted row: query for positions that are NULL, NaN, or outside a sane band (e.g. |pos| > 1e15) and reset them to normal values.
- Trigger a position rebalance/normalization for the affected list so all positions return to a small range.
- Guard client-side: refuse to use an anchor whose position is not a finite, modestly-sized number.
- If caused by writes from another tool, fix that tool to emit bounded positions.
Example fix
// before (corrupted row) UPDATE issue SET position = 1e308 WHERE id = '...'; // after UPDATE issue SET position = 0 WHERE id = '...'; -- or run the list rebalance job
Defensive patterns
Strategy: validation
Validate before calling
const POS_BOUND = 1e15;
function assertAnchorSane(anchor) {
if (!anchor) return;
const p = anchor.position;
if (!Number.isFinite(p) || Math.abs(p) > POS_BOUND) {
throw new Error(`anchor ${anchor.id} has corrupt position ${p}; refetch or rebalance the list`);
}
} Type guard
const isSanePosition = (p) => Number.isFinite(p) && Math.abs(p) < 1e15;
Prevention
- Never write positions from external tools without bounding them to a sane numeric range.
- Add a monitoring query for |position| > 1e15 or non-finite positions to catch corruption early.
- Run the list's rebalance/normalization job when corrupted positions are detected.
When it happens
Trigger: Move with a single before anchor whose stored position is close to math.MaxFloat64 (so +1 rounds to the same value or the value is already Inf), or an after anchor near -MaxFloat64 / equal to -Inf (so -1 yields Inf/NaN behavior). Realistically only reachable via corrupted rows or directly crafted API calls.
Common situations: A bug or manual SQL write leaving an issue position at an extreme value, then dragging relative to it; fuzzing or pen-testing the move endpoint with extreme floats; NaN positions inserted through some other path and used as an anchor.
Related errors
- move anchors are stale or out of order
- move anchors are too close; refresh and retry
- delete runtime: runtime has active agents bound to it (%s);
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/27a2e6fe8d050272.
Report an issue: GitHub.