Skip to content

Instantly share code, notes, and snippets.

@sibljon
Created March 26, 2026 11:00
Show Gist options
  • Select an option

  • Save sibljon/747aaee52f493a31947957c692cd8795 to your computer and use it in GitHub Desktop.

Select an option

Save sibljon/747aaee52f493a31947957c692cd8795 to your computer and use it in GitHub Desktop.
Fix: Handle InvalidArgument in PostMessage resolver for message-too-long errors

Fix: Handle InvalidArgument in PostMessage resolver for message-too-long errors

Context

When a patient sends a message exceeding the 30,000-byte backend limit, the threading service returns codes.InvalidArgument. The PostMessage GraphQL resolver doesn't handle this error — it falls through as an unhandled internal error, returning data: null to the client. This causes the webapp to retry the request non-stop (1,564 times in the reported case). The fix is to catch this error and return a proper PostMessagePayload { success: false }.

Steps

1. Add MESSAGE_TOO_LONG to the GraphQL schema enum

File: backend/cmd/svc/baymaxgraphql/internal/schema/baymaxgraphql.graphql (line 1113-1114)

Add a new enum value to PostMessageErrorCode:

  "The message text exceeds the maximum allowed length."
  MESSAGE_TOO_LONG

2. Regenerate schema code

cd backend && go generate ./cmd/svc/baymaxgraphql/internal/schema

This generates the Go constant PostMessageErrorCodeMessageTooLong in baymaxgraphql.graphql.go.

3. Handle InvalidArgument in the PostMessage resolver

File: backend/cmd/svc/baymaxgraphql/internal/resolvers/mutation_post_message.go (lines 108-126)

After the existing invalidAttachmentError and ErrorCodeReadOnly checks, add a check for codes.InvalidArgument:

if errors.GRPCStatusCode(err) == codes.InvalidArgument {
    return &schema.PostMessagePayload{
        Success:      false,
        ErrorCode:    schema.PostMessageErrorCodeMessageTooLong,
        ErrorMessage: "Message is too long.",
    }, nil
}

This goes before the final return nil, errors.Trace(err) at line 125. It follows the exact same pattern as the ErrorCodeReadOnly check above it.

Note: codes.InvalidArgument from r.postMessage() could theoretically come from other RPCs called inside that function (e.g., transformRequestToMessagePost, determineOutboundEndpoints). However, examining those code paths, they don't return InvalidArgument — and even if they did, returning MESSAGE_TOO_LONG for any InvalidArgument from the post-message flow is a reasonable user-facing response. The alternative (checking the error message string) would be brittle.

4. Add test: PostMessage returns MESSAGE_TOO_LONG on InvalidArgument

File: backend/cmd/svc/baymaxgraphql/internal/resolvers/mutation_post_message_test.go

Add a new test TestPostMessage_MessageTooLong that:

  1. Sets up the standard test models and context (same as existing tests)
  2. Mocks Thread() to return a valid thread
  3. Mocks CanPostMessage() to succeed
  4. Mocks DevicesForIDs() to succeed
  5. Mocks PostMessage() to return status.Errorf(codes.InvalidArgument, "Message text is 55659 bytes which is longer than max allowed of 30000")
  6. Sends the mutation and asserts the response is { "data": { "postMessage": { "success": false, "errorCode": "MESSAGE_TOO_LONG", "errorMessage": "Message is too long." } } }

This test is simple because most of the setup is the same as existing tests — it just changes the mock return value for PostMessage().

5. Run goimports and lint

goimports -w backend/cmd/svc/baymaxgraphql/internal/resolvers/mutation_post_message.go
goimports -w backend/cmd/svc/baymaxgraphql/internal/resolvers/mutation_post_message_test.go
cd backend && ./runlint.sh ./cmd/svc/baymaxgraphql/...

6. Run the test

cd backend && go test -run TestPostMessage_MessageTooLong ./cmd/svc/baymaxgraphql/internal/resolvers/

Verification

  1. Unit test passes with correct success: false, errorCode: MESSAGE_TOO_LONG, errorMessage response
  2. Lint passes
  3. Existing PostMessage tests still pass
  4. Optional: re-test in dev Chrome to confirm the webapp no longer retries (it should show the error toast and stop)

Files to modify

  • backend/cmd/svc/baymaxgraphql/internal/schema/baymaxgraphql.graphql — add enum value
  • backend/cmd/svc/baymaxgraphql/internal/schema/baymaxgraphql.graphql.go — regenerated
  • backend/cmd/svc/baymaxgraphql/internal/resolvers/mutation_post_message.go — add error handling
  • backend/cmd/svc/baymaxgraphql/internal/resolvers/mutation_post_message_test.go — add test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment