Observed on main @ 67791060 (server/index.ts), during end-to-end testing of a live deployment.
What happens
fetch resolves a thought with .single():
const { data, error } = await supabase
.from("thoughts")
.select("id, content, metadata, created_at, updated_at")
.eq("id", id)
.single();
if (error) {
return { content: [{ type: "text", text: `Fetch error: ${error.message}` }], isError: true };
}
On zero rows, .single() fails with PostgREST PGRST116 ("JSON object requested, multiple (or no) rows returned" / "Results contain 0 rows"), and the handler surfaces that raw message. So fetching a valid-but-absent id — e.g. one just deleted, or a stale id from an earlier search — returns an internal coercion error rather than a clean not-found.
Why it matters
- Leaks PostgREST internals and reads like a server bug to clients.
- Inconsistent with
update_thought / delete_thought, which fetch-first and return a clean Thought not found: <id>.
- The
search → fetch connector flow can easily reference an id that no longer exists.
Suggested fix
Handle the zero-rows case explicitly — use .maybeSingle() and return a clean not-found when data is null:
const { data, error } = await supabase.from("thoughts").select(/* ... */).eq("id", id).maybeSingle();
if (error) return { content: [{ type: "text", text: `Fetch error: ${error.message}` }], isError: true };
if (!data) return { content: [{ type: "text", text: `Thought not found: ${id}` }], isError: true };
(Or special-case error.code === 'PGRST116'.) This mirrors the not-found handling already used by the update/delete integrations.
Observed on
main@67791060(server/index.ts), during end-to-end testing of a live deployment.What happens
fetchresolves a thought with.single():On zero rows,
.single()fails with PostgRESTPGRST116("JSON object requested, multiple (or no) rows returned" / "Results contain 0 rows"), and the handler surfaces that raw message. So fetching a valid-but-absent id — e.g. one just deleted, or a stale id from an earliersearch— returns an internal coercion error rather than a clean not-found.Why it matters
update_thought/delete_thought, which fetch-first and return a cleanThought not found: <id>.search→fetchconnector flow can easily reference an id that no longer exists.Suggested fix
Handle the zero-rows case explicitly — use
.maybeSingle()and return a clean not-found whendatais null:(Or special-case
error.code === 'PGRST116'.) This mirrors the not-found handling already used by the update/delete integrations.