ruvnet/RuView · error · RangeError
guidance query must contain 2..500 characters
Error message
guidance query must contain 2..500 characters
What it means
require_role(...)'s decorator wrapper (auth.py:403) raises AuthorizationError('Authentication required') when request.state.user is None - i.e. the auth middleware never attached a user to this request. This is an ordering/wiring error, not a credentials error: the route is decorated for roles but runs before/untogether with AuthenticationMiddleware.
Source
Thrown at harness/homecore/src/guidance.js:78
throw new TypeError('guidance topic must be a string');
}
if (input.query !== undefined && typeof input.query !== 'string') {
throw new TypeError('guidance query must be a string');
}
if (input.limit !== undefined && (typeof input.limit !== 'number' || !Number.isFinite(input.limit))) {
throw new TypeError('guidance limit must be a finite number');
}
if (options.repoRoot !== undefined && options.repoRoot !== null && typeof options.repoRoot !== 'string') {
throw new TypeError('guidance repoRoot must be a string or null');
}
const topic = input.topic === undefined ? 'overview' : input.topic;
if (!GUIDANCE_TOPICS.includes(topic)) {
throw new RangeError(`unsupported guidance topic: ${topic}`);
}
const query = input.query === undefined ? '' : input.query.trim();
if (query && (query.length < 2 || query.length > 500)) {
throw new RangeError('guidance query must contain 2..500 characters');
}
const rawLimit = input.limit === undefined ? 20 : input.limit;
if (rawLimit < 1 || rawLimit > 20) {
throw new RangeError('guidance limit must be between 1 and 20');
}
const limit = Math.floor(rawLimit);
const wanted = tokenize(query);
const candidates = CAPABILITIES
.filter((capability) => topic === 'overview' || capability.topics.includes(topic))
.map((capability, order) => ({
capability,
order,
score: scoreCapability(capability, wanted),
}))
.filter(({ score }) => score > 0)
.sort((a, b) => b.score - a.score || a.order - b.order)
.slice(0, limit)View on GitHub (pinned to 4685618388)
Solutions
- Install the middleware: app.add_middleware(...) with get_auth_middleware(settings) so request.state.user gets populated
- Keep role-protected routes under /api/ so _requires_auth triggers authentication
- Alternatively use the FastAPI dependency require_role(role) (auth.py:445) which raises a proper 401 itself
Example fix
# before
@app.get('/admin/stats')
@auth_middleware.require_role('admin')
async def stats(request: Request): ...
# middleware never added
# after
app.add_middleware(AuthenticationMiddleware, ...) # or get_auth_middleware(settings) wiring
@app.get('/api/admin/stats')
@auth_middleware.require_role('admin')
async def stats(request: Request): ... Defensive patterns
Strategy: validation
Validate before calling
def middleware_wired(app) -> bool:
"""require_role's decorator reads request.state.user, set only by the middleware."""
return any("AuthenticationMiddleware" in str(m.cls) for m in getattr(app, "user_middleware", [])) Type guard
def request_has_user(request) -> bool:
return getattr(getattr(request, "state", None), "user", None) is not None Try / catch
from src.middleware.auth import AuthorizationError
try:
return await func(request, *args, **kwargs)
except AuthorizationError as e:
if str(e) == "Authentication required":
raise HTTPException(401, detail=str(e), headers={"WWW-Authenticate": "Bearer"})
raise HTTPException(403, detail=str(e)) Prevention
- Always install AuthenticationMiddleware when using the decorator
- Prefer the dependency form require_role() which fails with clean HTTP errors
- Mount protected routes under /api/ so auth actually runs
When it happens
Trigger: Applying @require_role('admin') to a route while AuthenticationMiddleware is not installed (get_auth_middleware never added to app); middleware ordering puts the route handler before auth runs; the request path is excluded from auth (not /api/* or /ws/*) yet the decorator still expects a user.
Common situations: Adding role-guards to routes in a new app instance where auth middleware was forgotten; testing route handlers directly (TestClient without middleware); paths outside /api/ that skip auth by design but are decorated anyway.
Related errors
- brain line ${index + 1}: exceeds 16 KiB
- brain line ${index + 1}: ${error.message}
- guidance topic must be a string
- guidance limit must be between 1 and 20
- prompt must be a non-empty string
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/20e2533f4d122e78.
Report an issue: GitHub.