fix: Make action attempt error and result nullable - #1007
Open
razor-x wants to merge 3 commits into
Open
Conversation
The generated ActionAttempt type collapsed the per-status API variants and claimed non-null error and result on every variant, so reading result on a pending attempt or error on a successful one typechecked and crashed at runtime. The API sends null for result unless the status is success and null for error unless the status is error. The blueprint merges the per-status variants and keeps the non-nullable property definitions, so normalize the action attempt properties during generation: error and result are nullable with the null semantics documented. SucceededActionAttempt and FailedActionAttempt now assert the resolved shape, so narrowing through resolveActionAttempt or a status check keeps result and error reads compiling. Guard SeamActionAttemptFailedError against a failed attempt without an error object instead of crashing with a null dereference. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B8xeJm2Hd923k8uo6eoFd2
…x115l-h6-action-attempt-types
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B8xeJm2Hd923k8uo6eoFd2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
SDK audit finding H6 (high): the generated
ActionAttempttype collapses the API's per-status variants (21 action types × 3 statuses) and claims non-nullerrorandresulton every variant:SucceededActionAttempt<T> = T & {status:'success'}was an intersection that recovered nothing, andSeamActionAttemptFailedErrorreadactionAttempt.error.messageunguarded.Fix
Root cause is upstream:
@seamapi/blueprint'screateActionAttemptsmerges the per-status OpenAPI variants and deliberately keeps the non-nullableerror/resultdefinitions — the JS templates already renderisNullablecorrectly. So the fix is a codegen normalization (mirroring seamapi/php#479, which faced the same blueprint limitation and also keptaction_type-discriminated variants): markerrorandresultnullable on every action-attempt variant and append the same doc sentence PHP uses — "Null while the action attempt is pending or when this value does not apply."Regeneration touches exactly one generated file,
src/lib/resources/action-attempt.ts(21 variants ×error+result).Hand-written follow-through in
resolve-action-attempt.ts:SucceededActionAttempt<T>assertsresult: NonNullable<T['result']>; error: null, andFailedActionAttempt<T>the mirror — so(await seam.locks.unlockDoor(...)).result.was_confirmed_by_devicekeeps compiling and is now actually safe.SeamActionAttemptFailedErrorfalls back to'Action attempt failed'/ code'unknown'for a failed attempt without an error object instead of crashing on a null dereference.Breaking-change note
Compile-time-only tightening that fixes a type lie — runtime behavior of well-formed responses is unchanged (the API always sent null). Code reading
aa.error.x/aa.result.xon an unnarrowed attempt stops compiling, which is the point; narrow viaresolveActionAttempt/waitForActionAttemptor a status check. PHP shipped its analog as afeat:in a minor.Tests
error/resultreads are@ts-expect-error;SucceededActionAttempt/FailedActionAttemptnarrowing compiles. On reverted source these produce 4 type errors — proving the old types lied.error: nullrejects withSeamActionAttemptFailedError('Action attempt failed', code 'unknown'); on reverted source this is a bareTypeError: Cannot read properties of null (reading 'message').Full suite (127 tests), lint, typecheck green.
npm run generatediff verified to touch only the expected sites.Part of applying the rev-3 SDK audit (one PR per finding). Related: #1002–#1006.
🤖 Generated with Claude Code
https://claude.ai/code/session_01B8xeJm2Hd923k8uo6eoFd2
Generated by Claude Code