Skip to content

Hard-coded fields masks silently drop unlisted API fields across services #384

@allenhutchison

Description

@allenhutchison

Problem

Several service methods request explicit Google API fields masks. Because these APIs return only the fields named in the mask, any field a caller might reasonably expect that isn't listed is silently dropped — no error, no log, just missing data. The failure mode is always a silent undefined, which is easy to miss in review and in production.

This was just surfaced concretely by #383: CalendarService.listEvents omitted attachments from its mask, so native event attachments vanished from every result even though getEvent (which uses no mask) returned them. #383 fixes that one field; this issue tracks the broader recurring pattern.

Affected read-path masks

These are masks on read paths where a caller could plausibly expect more than the mask returns (write-side update*Request masks are a different, correct use and are not in scope):

  • workspace-server/src/services/CalendarService.ts:493 (listEvents) — even after fix(calendar): include attachments in listEvents field mask #383, still omits location, organizer, recurringEventId, conferenceData (Meet links), hangoutLink, colorId, visibility, reminders.
  • workspace-server/src/services/DriveService.ts:315 (listFiles) — files(id, name, modifiedTime, viewedByMeTime, mimeType, parents); omits commonly-expected webViewLink, owners, size, trashed, shortcutDetails.
  • workspace-server/src/services/DriveService.ts:66 (findFolder, files(id, name)) and DriveService.ts:433 (getComments) — narrow, purpose-built masks; lower risk but same drop-silently semantics.
  • workspace-server/src/services/DocsService.ts:84 (getSuggestions, fields: 'title,body') — drops everything else in the document resource; intentional for its narrow purpose, but same pattern.

Why it's a maintenance liability

The masks are inline string literals, often duplicated between the service and its tests (e.g. the listEvents mask now appears in the source plus two test assertions). Adding any field requires editing multiple literals, and nothing flags when an expected field is missing.

Proposed direction (for a separate PR)

  1. Audit each read-path mask and add fields the tools/callers actually need.
  2. Extract masks into named, per-resource constants — following the existing TABS_FIELD_MASK pattern in DocsService.ts:17 — so masks are discoverable, reviewable in one place, and assertable in tests without copy-pasted literals.
  3. Update tests to assert against the shared constant rather than duplicated strings.

Context

Surfaced during the review of #383 (silent-failure analysis). Not a blocker for #383 — that PR correctly fixes the attachments case in isolation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions