distinguish-not-found-from-errors

distinguish-not-found-from-errors is a cursor rule for Cursor from PaulJPhilp/EffectPatterns. It costs 625 tokens per session, scanned A, original, MIT.

A result type that separates a missing record from a real failure, such as a database outage.

In plain words
What is it for?
Use it when database lookups or similar operations may return nothing or fail in a TypeScript Effect program.
Why use it?
It stops callers from treating “no matching user” as if the database itself had broken.

Cursor rule for Cursor

Written for Cursor: a Cursor rule (.mdc).

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add rules/pauljphilp/effectpatterns/distinguish-not-found-from-errors
Clone the repo
git clone --depth 1 https://github.com/PaulJPhilp/EffectPatterns

Made for: Cursor.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for distinguish-not-found-from-errors

README.md
[![agentmods](https://agentmods.dev/badge/rules/pauljphilp/effectpatterns/distinguish-not-found-from-errors.svg)](https://agentmods.dev/rules/pauljphilp/effectpatterns/distinguish-not-found-from-errors)
Your own site
<a href="https://agentmods.dev/rules/pauljphilp/effectpatterns/distinguish-not-found-from-errors"><img src="https://agentmods.dev/badge/rules/pauljphilp/effectpatterns/distinguish-not-found-from-errors.svg" alt="Measured on agentmods" height="20"></a>
Per session 625 This file is loaded in full into every session.
When invoked 625 The same file — it is already loaded in full.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00625 $0.00625
Opus 5 $0.00313 $0.00313
Sonnet 5 $0.00125 $0.00125
Haiku 4.5 $0.00063 $0.00063

Measured 2d ago against content hash 2beaa4659149, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-06, from the pricing page.

Security

Grade A, and why

distinguish-not-found-from-errors scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

content/published/rules/cursor/distinguish-not-found-from-errors.mdc · 74 lines

How it starts

The opening of the file, as written. The whole thing — 74 lines — stays where its author put it; the contents beside it link to each section on GitHub.

description: Use Effect<Option> to distinguish between recoverable 'not found' cases and actual failures. globs: "**/*.ts" alwaysApply: true

Distinguish 'Not Found' from Errors

Rule: Use Effect<Option> to distinguish between recoverable 'not found' cases and actual failures.

Example

This function to find a user can fail if the database is down, or it can succeed but find no user. The return type Effect.Effect<Option.Option<User>, DatabaseError> makes this contract perfectly clear.

import { Effect, Option, Data } from "effect";

interface User {
  id: number;
  name: string;
}
class DatabaseError extends Data.TaggedError("DatabaseError") {}

// This signature is extremely honest about its possible outcomes.
const findUserInDb = (
  id: number
): Effect.Effect<Option.Option<User>, DatabaseError> =>
  Effect.gen(function* () {
    // This could fail with a DatabaseError
    const dbResult = yield* Effect.try({
      try: () => (id === 1 ? { id: 1, name: "Paul" } : null),
      catch: () => new DatabaseError(),
    });

    // We wrap the potentially null result in an Option
    return Option.fromNullable(dbResult);
  });

// The caller can now handle all three cases explicitly.
const program = (id: number) =>
  findUserInDb(id).pipe(
    Effect.flatMap((maybeUser) =>
      Option.match(maybeUser, {
        onNone: () =>
          Effect.logInfo(`Result: User with ID ${id} was not found.`),
        onSome: (user) => Effect.logInfo(`Result: Found user ${user.name}.`),
      })
    ),
    Effect.catchAll((error) =>
      Effect.logInfo("Error: Could not connect to the database.")
    )
  );

// Run the program with different IDs
Effect.runPromise(
  Effect.gen(function* () {
    // Try with existing user
    yield* Effect.logInfo("Looking for user with ID 1...");
    yield* program(1);

    // Try with non-existent user
    yield* Effect.logInfo("\nLooking for user with ID 2...");
    yield* program(2);
  })
);

Explanation:
This pattern provides a precise way to handle three distinct outcomes of an operation:

Read the full file on GitHub · 74 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 74 lines · 625 tokens per session scan A 2beaa4659149

Subscribe to this mod's changes

distinguish-not-found-from-errors is a cursor rule published in the GitHub repository PaulJPhilp/EffectPatterns (796 stars, last pushed 2mo ago), licensed MIT. It adds 625 tokens to every session, about $0.0031 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-03.