Flags shallow boolean result wrappers like { ok: true, data } and { success: false, error: ... }.
- Family:
api - Severity:
strong - Scope:
file - Requires:
file.ast
The rule looks for object literals that combine:
- a boolean status field:
successorok - a generic payload field such as
message,error,data,rows,present, orartifactId
This pattern is common in generated app/service glue that wraps every operation in a shallow result envelope. It is not always wrong, but repeated use often signals generic boolean-and-payload plumbing instead of richer domain-shaped APIs.
To avoid obvious vendored noise, the rule skips very large bundled/generated files over 5000 logical lines.
return { success: false, error: "Unauthorized" };
return { success: true, message: "Repository created successfully" };
return { ok: true, rows };
return { ok: true, artifactId: String(foundId) };return { ok: true };
return { success: true, user };
return { error: "missing" };Prefer API shapes that express the actual domain outcome instead of wrapping everything in a shallow boolean envelope.
Better options:
- return the domain object directly on success
- use typed result variants when callers really need success/failure branching
- model specific failure cases instead of pushing everything into generic
message/errorstrings
type CreateRepoResult =
| { kind: "created"; repository: Repository }
| { kind: "forbidden" }
| { kind: "conflict"; reason: string };A small { ok, data } wrapper is sometimes fine, but if it becomes the default shape for every operation it usually means the API is describing transport status rather than domain meaning.
Each generic status envelope adds 2 points.
The file total is capped at 8.
Small pinned rule benchmark (manifest):
- Signal rank: #2 of 9
- Signal score: 0.76 / 1.00
- Best separating metric: findings / file (0.88)
- Hit rate: 5/6 AI repos vs 2/5 mature OSS repos
- Full results: rule signal report