Follow-up to #756 (Category 2 from @scottschreckengaust's triage on #756). Part of #756.
Problem
Best-effort network/DDB reads whose null/[] return collapses "not found" into "lookup broke". Each already logs, so the failure is observable — but not actionable by the caller, and where these feed orchestration state a swallowed read changes control flow, not just presentation.
Sites (verified on the PR #788 branch)
Fix first — cdk/src/handlers/orchestration-reconciler.ts:1455: a bare catch { return null; } with no logging at all (the pr_url read above resolvePrNumber). Strictly worse than its neighbours.
Cheap — widen the return type to encode failure:
cdk/src/handlers/shared/slack-api.ts:112 — null conflates "no ts returned" with "Slack unreachable"
cdk/src/handlers/shared/linear-feedback.ts:280 — GraphQL transport failure ≡ empty data
cdk/src/handlers/shared/linear-subissue-fetch.ts:333 — "no parent" ≡ "parent lookup failed"; parent-vs-sub routing depends on this
cdk/src/handlers/shared/jira-feedback.ts:372 and :395 — transition lookup; :395 masks invalid JSON from Jira, a distinct class from a network timeout
cli/src/commands/linear.ts:1721 — queryLinearTeamKeys returns []; caller can't tell "no teams" from "auth failed"
Medium — these feed orchestration state (control flow, not presentation):
cdk/src/handlers/orchestration-reconciler.ts:1476 and cdk/src/handlers/linear-webhook-processor.ts:2757 — duplicated resolvePrNumber/resolveChildPrNumber (identical body, both swallow). Extract to one shared helper while fixing so the fix lands once.
cdk/src/handlers/orchestration-reconciler.ts:471 — combined screenshot read
cdk/src/handlers/shared/orchestration-rollup.ts:490 — epic panel upsert; null → "no panel id" → next edit silently posts fresh
cdk/src/handlers/github-webhook-processor.ts:448 — findIterationReplyId; a masked failure → duplicate top-level comment instead of a threaded edit (user-visible symptom)
cdk/src/handlers/linear-webhook-processor.ts:532 — iteration ack reply
Fix
Widen return types to encode failure (discriminated result / typed error), dedupe the two resolvePrNumber copies, and add logging to :1455. Add an inline nosemgrep only where the empty value is genuinely the contract (none expected in this bucket).
Related
Line numbers verified against the PR #788 branch. Credit: triage by @scottschreckengaust on #756.
Follow-up to #756 (Category 2 from @scottschreckengaust's triage on #756). Part of #756.
Problem
Best-effort network/DDB reads whose
null/[]return collapses "not found" into "lookup broke". Each already logs, so the failure is observable — but not actionable by the caller, and where these feed orchestration state a swallowed read changes control flow, not just presentation.Sites (verified on the PR #788 branch)
Fix first —
cdk/src/handlers/orchestration-reconciler.ts:1455: a barecatch { return null; }with no logging at all (thepr_urlread aboveresolvePrNumber). Strictly worse than its neighbours.Cheap — widen the return type to encode failure:
cdk/src/handlers/shared/slack-api.ts:112—nullconflates "no ts returned" with "Slack unreachable"cdk/src/handlers/shared/linear-feedback.ts:280— GraphQL transport failure ≡ empty datacdk/src/handlers/shared/linear-subissue-fetch.ts:333— "no parent" ≡ "parent lookup failed"; parent-vs-sub routing depends on thiscdk/src/handlers/shared/jira-feedback.ts:372and:395— transition lookup;:395masks invalid JSON from Jira, a distinct class from a network timeoutcli/src/commands/linear.ts:1721—queryLinearTeamKeysreturns[]; caller can't tell "no teams" from "auth failed"Medium — these feed orchestration state (control flow, not presentation):
cdk/src/handlers/orchestration-reconciler.ts:1476andcdk/src/handlers/linear-webhook-processor.ts:2757— duplicatedresolvePrNumber/resolveChildPrNumber(identical body, both swallow). Extract to one shared helper while fixing so the fix lands once.cdk/src/handlers/orchestration-reconciler.ts:471— combined screenshot readcdk/src/handlers/shared/orchestration-rollup.ts:490— epic panel upsert;null→ "no panel id" → next edit silently posts freshcdk/src/handlers/github-webhook-processor.ts:448—findIterationReplyId; a masked failure → duplicate top-level comment instead of a threaded edit (user-visible symptom)cdk/src/handlers/linear-webhook-processor.ts:532— iteration ack replyFix
Widen return types to encode failure (discriminated result / typed error), dedupe the two
resolvePrNumbercopies, and add logging to:1455. Add an inlinenosemgreponly where the empty value is genuinely the contract (none expected in this bucket).Related
Line numbers verified against the PR #788 branch. Credit: triage by @scottschreckengaust on #756.